17 ms·
There is a saying about the band Velvet Underground - that not many people bought their records, but everyone who bought one went out and started their own band
by olavk 8y ago
There is a saying about the band Velvet Underground - that not many people bought their records, but everyone who bought one went out and started their own band. I think Lisp is kind of similar - its influence is much larger than its fame, but ever language designer is inspired by it to some extent.
I do think Lisp kind of missed the boat when a wave of dynamic languages (Perl, Python, Ruby) went mainstream. Today the most exciting developments in language design seem to be around static type systems, type inference etc.
- yogthos 8y agoI think there is a lot of exciting stuff happening in Racket and Clojure around contract systems right now with things like Racket Contracts and Clojure Spec. This approach provides an appealing alternative to static typing because it focuses on semantic correctness while static typing focuses primarily on self consistency. In my view the former is much more valuable because ultimately we want to know that the code is doing what was intended, and static typing doesn't appear to be an effective tool for encoding intent.
- hashkb 8y agoI think Typed Racket has more buzz than contracts... maybe even seen as a replacement/evolution by many.
- Avshalom 8y agoI can't swear to this but I think they've gone basically hand in hand. I'm pretty sure I read a few Racket posts about how they use contracts to keep a safe interface between typed and untyped code and just in general between languages.
- samth 8y agoYes, this is correct. The recent explosion of work on gradual typing (including Typed Racket) was enabled by the development of contracts.
- jjtheblunt 8y agodoesn't appear? why?
- yogthos 8y agoBecause static typing primarily focuses on showing that your types align. This is completely tangential to knowing that the code is doing what you intended. In fact, it's often at odds with understanding the intent of the code because you're limited to a set of statements that can be verified by the type checker. This can make it harder for the human reader to understand what the code is meant to be doing. For example, it takes nearly 300 lines of code to encode insertion sort using types in Idris https://github.com/davidfstr/idris-insertion-sort/blob/master/InsertionSort.idr https://github.com/davidfstr/idris-insertion-sort/blob/maste... A human reader has to be able to read that and understand that the types are encoding the intent correctly. I don't know about you, but I have a much easier time knowing whether the dynamically typed version in Python is correct or not: def insertionSort(lst): for index in range(1, len(lst)): currentvalue = lst[index] position = index while position > 0 and lst[position - 1] > currentvalue: lst[position] = lst[position - 1] position = position - 1 lst[position] = currentvalue Complex type definitions effectively become their own meta-programs that the compiler uses to verify your program, but now you've just pushed the problem back a step since somebody still has to read and understand the meta-program to know that it's verifying the correct thing.
- mercer 8y agoIs Elixir/Erlangs Dyalizer/Dyalixir similar to Clojure's spec? I'd very much like to read more on this topic, but because my knowledge of type systems pretty much started with, and is limited to TypeScript, I don't know what to ask specifically. Have you written anything about this, or could you point me to any articles that discuss this difference? Basically, I've become convinced that TypeScript, at least for anything nontrivial, is worth using over just JavaScript. There's nothing like it in the Elixir world, but I've been meaning to check out Dialyzer because I do sometimes miss what TypeScript offers.
- stcredzero 8y agostatic typing doesn't appear to be an effective tool for encoding intent Static typing is about as effective at encoding intent as intention revealing names. That is to say, if you are diligent and clever in how you structure and name things, a system can be very intention revealing. HN user jerf has a method of revealing intent through types in golang, which he calls something like microtyping. Basically, everything has its own type, based on its domain semantics. So if you're using a float64 to store time deltas, you don't just use the float64. Instead, you base a TimeDelta type on float64. type TimeDelta float64 Then golang allows you to attach methods to that type, which can then provide more opportunities for intention revealing. Also, this prevents a programmer from mistakenly using a float64 representing width and shoving it into a time calculation. Is this as ironclad as Eiffel Design by Contract or Haskell typing? No. However, I've been using it myself, and I can affirm that yes, the compiler will warn you about some semantic errors if you do it this way. The big problem with the Intention Revealing Names pattern, is that there is no enforcement and that it is subjective. For this reason, it's likely to fall apart in a large enough project that lives long enough.
- vram22 8y ago>HN user jerf has a method of revealing intent through types in golang, which he calls something like microtyping. Basically, everything has its own type, based on its domain semantics. So if you're using a float64 to store time deltas, you don't just use the float64. Instead, you base a TimeDelta type on float64. >type TimeDelta float64 >Then golang allows you to attach methods to that type, which can then provide more opportunities for intention revealing. Also, this prevents a programmer from mistakenly using a float64 representing width and shoving it into a time calculation. IIRC, this technique, or something similar, is shown in The Go Programming Language book. F# also allows you to do similar stuff, I think.
- nikofeyn 8y agof# definitely allows this with single case discriminated unions. and in f#, you can add members to any type, which includes discriminated unions, records, classes, etc. in fact, you can add member functions somewhere else after the definition of the type. so you can define the type, write functional helper functions against that type and then later add member functions to the type that are defined in terms of the helper functions.
- digi_owl 8y agoBest i can tell, when it was introduced it massively outpaced any of the "consumer" hardware out there. End result was the whole issue of Lisp machines that was tailored to accelerate the language, possibly souring academia on the language in the process.