6 ms·
This looks incredibly ambitious: - There are no booleans in the language! Conditionals can still succeed or fail, but failure is defined as returning zero valu
by rkrzr 4y ago
This looks incredibly ambitious:
- There are no booleans in the language! Conditionals can still succeed or fail, but failure is defined as returning zero values and success is defined as returning one or more values.
- Verse uses a so-called 'lenient' evaluation strategy which is neither strict nor lazy, but somewhere in-between ("Everything is eventually evaluated, but only when it is ready")
- an expression does not evaluate to a value (like in Haskell), but instead to a sequence of zero or more values
- tries to bring functional logic programming into the mainstream
- Verse uses an effect system for I/O instead of monads
- A type in Verse is "simply a function". E.g. int is the identity function on integers, and fails otherwise
This all looks very mind-bending to me (in a good way). Perhaps Verse will one day be as influential for PL design as Haskell has been.
- bmitc 4y ago> Perhaps Verse will one day be as influential for PL design as Haskell has been. Has Haskell really been that influential though? It seems to me that MLs, Lisps, Schemes, and even Erlang have been more influential.
- cma 4y agoI think it influenced python list comprehensions.
- TuringTest 4y agoHaskell has been enormously influential in the study of types; modern high-level type checkers are built using knowledge from these studies.
- epolanski 4y agoIt's definitely the most influential of the statically typed functional languages. All other statically typed functional languages or libraries inherit a lot from Haskell implementations, type system and type class concepts.
- nullifidian 4y agoStandard ML is more influential because it's the foundational statically typed functional language. But Haskell has gained more popularity with the general programming public, not just academics.
- bmitc 4y agoWhat modern language in use today was influenced by Haskell other than maybe Idris? (To be clear, I am mot necessarily down on Haskell or what part it has played. It’s just that many languages seem to be stealing ideas from the languages I’ve listed more than Haskell, which was the criteria I had in mind.)
- xigoi 4y agoI'm pretty sure Haskell is the reason why True and False are capitalized in Python.
- nrioux 4y agoRust's traits come to mind as one example.
- bmitc 4y agoAs far as I can tell, from an admittedly short amount of searching and research, is that type classes in Haskell were influenced by Standard ML: https://people.csail.mit.edu/dnj/teaching/6898/papers/wadler88.pdf https://people.csail.mit.edu/dnj/teaching/6898/papers/wadler... > This paper presents type classes, a new approach to ad-hoc polymorphism. Type classes permit overloading of arithmetic operators such as multiplication, and generalise the "eqtype variables" of Standard ML. Type classes extend the Hindley/Milner polymorphic type system ... And it was my understanding that traits came more from the object-oriented world, such as Self and Smalltalk. Scala and Racket also had them before Rust, and Scala also has type classes.
- nrioux 4y agoPhil Wadler, the first author of the paper you cite, was literally a principal designer of Haskell. SML does not have type classes; your quote points out a deficiency in SML that motivates type classes. My understanding is that "trait" is an unfortunately overloaded term. Traits in Rust are much more closely related to Haskell's type classes than to traits in the OOP sense.
- nullifidian 4y agoThe first language to implement type classes. The first language to structure computation with monads, which are now omnipresent in functional languages.
- stefano_c 4y ago> - There are no booleans in the language! Conditionals can still succeed or fail, but failure is defined as returning zero values and success is defined as returning one or more values. This is similar to how Icon works: https://en.m.wikipedia.org/wiki/Icon_(programming_language) https://en.m.wikipedia.org/wiki/Icon_(programming_language)
- truculent 4y agoSounds like it's not a million miles away from how Clojure treats `nil` values, either
- deleted 4y ago[deleted]
- mikelevins 4y agoYes, I noticed that, too. I used Icon to process a big pile of code at Apple in the late 80s and found it pleasant to work with.
- stefano_c 4y agoI wish I could upvote comments more than once on HN :-)
- DuncanMak 4y agoThis article seems like a nice overview of the pros and cons of the Icon expression evaluation system: https://tratt.net/laurie/research/pubs/html/tratt__experiences_with_an_icon_like_expression_evaluation_system/ https://tratt.net/laurie/research/pubs/html/tratt__experienc...
- galaxyLogic 4y ago> sequence of zero or more values You can try this type of programming at home, say in JavaScript Make any result or argument be an Array. The problem with nulls goes away because "not there" is represented simply by an empty Array (a.k.a "sequence"). And you will not get null-errors because you can write: newValue = someValue.filter(...) . map(...) ; You don't need to test whether filter() returns an empty array or not, the map() will work for empty arrays too but simply do nothing. This is in a sense "generalized programming" because you don't deal with individual values but always with collections of them. I sometimes wonder why I don't use this pattern more often.
- eyelidlessness 4y agoI had similar thoughts (I do JS/TS dev daily but I’m very interested in a lot of what this language appears to offer). But I’d caution trying this with JS for anything more than exploring the ideas presented by the pattern. The reality is that even adding a type checker like TypeScript, and as many lint rules as you can throw at a project, it’s still too easy to end up putting nullish values into your null-safe arrays. And I similarly wondered why I don’t use this sort of pattern more often, but that wondering is what led me to add this caution. It’s a really compelling idea, but probably extremely hard to debug when it goes wrong in a language and idiomatic ecosystem designed for it to go wrong at any time.
- galaxyLogic 4y agoI guess one reason is that it takes more code to return an Array when in most cases what the caller needs is always just a single value. Many such functions never return null so it is overhead to make them return an array. But returning an array also makes your functions more general. Maybe in the future you want to modify it so that it does return arrays of length > 1. Evolving the program to that state is then easy if you didn't lock yourself into assumption that this function will never ever need to return more than a single value.
- valenterry 4y agoBecause now you can't differentiate between an actual empty array or an error. That's horrible. Or, you actually have to use nested arrays to describe that the result might be an error or an array. But now you have to deal with an array which might contain... zero errors or even multiple ones. That's really not a great way of doing things. Instead, do it the other way around and make null treatable in the same way as arrays are. And if you do that, you end up with what languages like Haskell do.
- Throwaway23459 4y ago> so-called 'lenient' evaluation strategy which is neither strict nor lazy, but somewhere in-between Sounds like we are still clinging on to laziness in some regard, I wish we could get shod of it entirely. Although laziness makes doing Leetcode problems in Haskell really fun, Idris got it right when they opted for strict evaluation for predictable memory performance.
- agumonkey 4y agoSurprised about the syntax. Curlies still hold a lot of power :)
- zozbot234 4y ago> This all looks very mind-bending to me (in a good way). Perhaps Verse will one day be as influential for PL design as Haskell has been. I'm not convinced. Making non-determinism a first-class feature in the language might be good if you simply care about logical specifications that might enable you to prove something correct, but a real-world program implementation has to make heuristic choices for efficiency as to when to evaluate what (and perhaps where, especially in a parallel/distributed setting), and just stating that evaluation is "lenient" isn't really saying anything worthwhile. So this kind of design choice will ultimately be expressed with ugly hacks, as with e.g. Prolog where the 'cut' feature is used to override the default search strategy.
- FullyFunctional 4y agoBut it's very much not non-deterministic. It's a deterministic choice. You can give it an exact semantics.
- zozbot234 4y agoHow? The slide deck calls it a "lenient" evaluation order, and doesn't really say how to make an explicit choice of what cases should be tried first. So it seems to have all the same problems as naïve Prolog.
- disconcision 4y agoexact semantics are given here: https://simon.peytonjones.org/assets/pdfs/verse-conf.pdf https://simon.peytonjones.org/assets/pdfs/verse-conf.pdf. runtime efficiency isn't specifically addressed afaict
- cryptonector 4y agoCorrect, but "non-determinism" is a misnomer used in programming language theory to refer to generators and pervasive backtracking. Prolog, Icon, jq, etc. -- all fully deterministic, but known as non-deterministic owing to the pervasive generators and backtracking.
- FullyFunctional 4y agoThere's really not much new here. All these ideas have been used in other languages previously, but perhaps not in exactly this cocktail. I'm decidedly in the not convinced camp.
- imtringued 4y agoI am not convinced because far more pressing aspects have been ignored. One million programmers means program structure is more important than the syntax used to write the algorithms. Does the language address common pain points like modifying data structures? Does it make it easy to extend existing code even without having the ability to change it?
- cryptonector 4y agoIcon had (has!) "failure is falsity" / "value production is truth", and pervasive generators / backtracking. In Icon a function ("procedure") either: fails, returns a value, or suspends (yields) a value. jq is very much like this too, as it has pervasive generators and backtracking, but unlike Icon jq does not distinguish between "returning" a value vs. "suspending" (yielding) a value. The jq way kinda means you have to have booleans, and so jq does. I'm suspicious of the no-booleans approach. After all, one could also have no integers (the Lambda Calculus doesn't have integers, having only function values!). Boolean values are just useful to have, and being able to obtain boolean values from predicates is useful too. One could do the Icon/Verse thing of failure is false / anything is true, but provide an adapter function that produces actual boolean values for when you need them.
- reacweb 4y agoI was suspicious of javascript where number replaces int and double. The fail in verse is a way to replace boolean and null values. I think it is the direction of evolution.