<https://nim-lang.org/blog/2019/09/23/version-100-...
# linking-together
g
paging @Edward de Jong / Beads Project as nim claims to be inspired partially by modula
e
There are strong elements of Modula-2 and Oberon in Nim, however, i wouldn't call it a simple language like Prof. Wirth's creations. Nim has a lot of fancy stuff, and to me it more of a fusion between Java and M2/Oberon than a purely new thing. It has unfortunately inherited horrible things like closures, and try/catch, which have been proven to create problems.
b
Why are closures horrible?
๐Ÿ‘ 2
w
I don't know what @Edward de Jong / Beads Project has in mind, but, for example, closures can capture more state than you mean for them to, make GC harder than you would like, can be opaque and non-deterministic in weird ways. (Not that objects aren't, but sometimes you can ask them what are your instance variables and how are they changing over time?)
y
Closures are great imho. I remember when going from C++ to Python I pleasantly discovered that pretty much all of those complicated design patterns are things you do without even thinking about it with closures and first-class functions. When later discussing with lisp folks about macros I also figured that most examples for the usefulness of macros can be solved better by closures.
๐Ÿ‘ 3
๐Ÿ˜• 1
g
๐Ÿ‘ 1
Copy code
16 of 23 patterns are either invisible or simpler, due to: 
First-class types (6): Abstract-Factory, Flyweight, Factory-Method, State, Proxy, Chain-Of-Responsibility
First-class functions (4): Command, Strategy, Template-Method, Visitor
Macros (2): Interpreter, Iterator
Method Combination (2): Mediator, Observer 
Multimethods (1): Builder
Modules (1): Facade
โค๏ธ 1
a
Edward replied "This is almost exactly how my Beads language is designed." to https://awelonblue.wordpress.com/2012/10/21/local-state-is-poison/ a while ago, so that's probably the idea.
๐Ÿค” 1
y
@alltom thatโ€™s an interesting article. Goes against my programming habits but that doesnโ€™t necessarily mean itโ€™s wrong
s
Exceptions are basically 'goto' where the destination is dynamically determined. Closures outlive their outer function and fork the lifetime beyond that function. I actually prefer to use both instead of the other usual alternatives which I find very cumbersome. However if there were non cumbersome alternatives I could change my mind.
๐Ÿ‘ 1
e
Closures are very bad for some important reasons: 1) they create a bizarre chunk of code which is partially instantiated with values. It is very common in JS to create a function that is parameterized via a closure. So effectively you are creating a section of code that has no location in your code base; it is a mixture of data and code together, living on the heap, that requires some magic in the runtime to make it all work (with attendant magical garbage collection when the closure is finished). 2) if you are trying to show the state of the computer in its totality, it greatly complicates the display: you have your code in one window, and your data in another window, and a closure is a hybrid of the two, and depending on how many of them you have it could make a real mess. 3) it makes it almost impossible to reverse the execution of your program. Every programmer should be honest about where they spend their time. It isn't typing in code, or designing. There is an activity which consumes I estimate around 80% of one's time, and it is the hard part that causes people to quit the field.... debugging. And isn't debugging in its essence the process of going from an effect back to its cause, following the long chain of cause and effect that is how computers actually work. That being said, there is almost no way to program sensibly in JS without using them, with its callback system which relies on the closures to remember the local variable context so that the callback function can do useful work without having tons of parameters and going the extra mile one had to do back in mainframe days when all functions were re-entrant by design, and you had to pass storage buffers to the called function so that no memory allocations were happening inside some low level code. those were painful days with tons of housekeeping and boilerplate to make it all work. Today's closures are fairly painless. But it doesn't mean they don't rely on a very sneaky system that is poorly understood by the people using them.
๐Ÿ‘ 2
w
If we exclude event handling callbacks and blocks (functions whose life is shorter than their calling context and therefore don't need to "close" per se), how often are closures proper used in the wild? (Functional programmers please put your hands down and go back to eating your curry.)
g
From clojure in contrast to JS, I think closures are much safer if you deal only in immutable data and no implicit refs like
this
, but you still add a lot of complexity that might be better served by being explicit (using a record or data structure to be interpreted later), for example if you decide you want to serialize your functions and parameters and execute them on another machine. A company I worked for had this problem when using clojure to define java hadoop/mapreduce jobs, and we created some nasty workarounds.
in ocaml, you create closures so often and for so many use-cases they lose all meaning
I'm not convinced monadic async programming is a good thing, it's just the tool we have.
w
@Gary Trakhman eat your curry! ๐Ÿ˜„ Honestly though, my inner diehard dynamic language radical runtime transparency fan feels that the problem with closures is that we usually hide the context and make it practically impossible to get at!
โ˜๏ธ 1
g
I am the reluctant ocaml programmer. There's dozens of us.