If you created your own programming language...

This is an interesting thread. :smile: A couple things struck me that I want to comment on.

Iā€™m all for defining function blocks with {}. I donā€™t think anything has to separate functions from any other code block because theyā€™re semantically the same. Theyā€™re not implemented the same way for performance reasons, but a compiler can tell how youā€™re using the block without annotation. (If it comes after while and itā€™s not assigned to anything, itā€™s inline. If itā€™s assigned and referred to elsewhere, compile it as a closure.)

Autoclosures are an awesome compromise between lazy and strict evaluation, which gives you significant power to create new language features. You just have to assume that every library author is smart and sane and friendly. Which I do.

Iā€™m also all for the consolidation features @senocular proposed. You can almost do it automatically with code thatā€™s commented for clarity. Take kirupaā€™s post on merge sort in JavaScript:

function mergeSort(input) {
  if (can't divide further) {
    return input;
  }

  divide the array in half
  recursively sort and merge
}

function merge(left, right) {
  var result = [];

  order the sublist as part of merging
  add the remaining items to the result
  the sorted sublist

  return result;
}

(which isnā€™t perfect, but as you can see, could be super readable with a few tweaks.)

Iā€™d like to do away with the requirement that you must name something to refer to it in more than one place. Tuples are records without keys. Why not variables without names?

The language would support Jonathan Edwardsā€™ schematic tables (conditional logic written as truth tables) (screenshot). They make logic like in your example:

if hiddenCondition {
   hiddenMethod()
} else {
   if hiddenCondition2 {
      hiddenMethod()
   } else {
      hiddenMethod2()
   }
}

and every equivalent form, such as:

if hiddenCondition || hiddenCondition2 {
   hiddenMethod()
} else {
  hiddenMethod2()
}

all collapse to the same structure, which is easier to reason about, refactor, and maintain. (Iā€™m having trouble convincing myself that the second version is actually equivalent to the first, even though Iā€™m pretty sure it is. This is why notation mattersā€¦)

Also, we love to rag on Java, but Iā€™ve been writing Java at work all day and I have to say that dependency injection is amazing. It is the programmer equivalent of reaching out from under the car, announcing, ā€œsocket wrench,ā€ and having one materialize in your hand. As far as Iā€™m concerned, we should be injecting everything everywhere always. Decouple all the things!

The language would also let you inject the user. If youā€™re not sure how to implement some behavior, inject yourself and be in charge of turning the parameters into a return value and side effects manually. You can abstract and encode that into a programming notation laterā€¦


And this isnā€™t an idea for a language, but itā€™s something I keep in mind when Iā€™m thinking about ideas for programming languages: cognitive dimensions of notations. In particular, programming is not one activity. Itā€™s several (writing, reading, debugging, etc). And ā€œeach activity is best served by a different trade-off in the usability on each dimension.ā€ In fact, if I could write code in Ruby, but refactor it in Haskell, debug it in Smalltalk, and deploy it in JavaScript, that would be great.

Thatā€™s why Iā€™m right on board when @krilnon says programming languages shouldnā€™t round off every corner in the name of protecting us from ourselves. Because they shouldnā€™t ā€¦ up until the point when we move from designing and writing code to maintaining its current behavior. At that point Iā€™m all for language features that help you not accidentally break things.

1 Like