50 comments

[ 5.3 ms ] story [ 115 ms ] thread
> min, max = bounds(x)

Doesn't Python already de-structure?

Repackaged: does PyFL lose touch with the regular language?

I had the same thought. There was surprisingly little discussion of how this new language relates to Python - the only mention on the whole page is that need Python installed to use it. At pyflang.com it says that "PyFL = Python based Functional Language".

I'd be curious to know: Does PyFL benefit from Python's libraries, in the way that Scala and Clojure can use Java libraries? Are there any syntactic similarities? Or does it just happen to be built on Python as an implementation detail?

My bad, it's implemented in Python. But it uses one Python library, mathplotlib,although I commented out the code cause mathplotlib is a pain to install.
I believe it’s PyFL… fyi not to troll :)
Fixed above. Thanks!
Is PyFL pronounced 'piffle'?
I humbly suggest 'pie-full' because mmmmmmm.
Interesting. I'm not aware of any other lazy dynamic languages. I would assume it is difficult to optimise such a combination.
Indeed, these languages are descendants of ISWIM by Peter Landin.

ISWIM also inspired Lucid, so I guess PyFL would be a nephew of SASL in that case.

ISWIM isn't lazy, I think, nor fully functional.
Right, but it’s still the root of the functional branch of the PL family tree. ISWIM to ML is mostly a matter of removing the few imperative features from ISWIM. Once you do that, lazy execution comes naturally.
Clojure? It's not purely lazy, but with liberal use of `seq`s it pretty much is.
> … valof clauses (basically where clauses)

I so wish Python had valof/where already. And it’s the one feature I was surprised not to find in OCaml after seeing it in Haskell – why isn’t it more common?

What is it?
It's the syntax that allows you to write

    x + y
    where y = g(x, 17)
    where x = f(42)
instead of

    let x = f(42) in
    let y = g(x, 17) in
    x + y
Similar to 'let' (or 'letrec' in lisps), but written after the block it applies to. For example:

    average xs = total / count
      where total = sum xs
            count = length xs
Ah, I see, it's the "where" that is natural in mathematics.
Right. Bindings instead of (procedural) assignments. Perhaps: valof(<expr>) where(<bindings>)
best define `average []` first
Heh; better to use a non-empty list (AKA a tuple) I suppose. It's also wildly inefficient compared to:

    average (x, xs) = total / count
      where (total, count) = Data.List.foldl' go (x, 1) xs
            go (total, count) x = (total + x, count + 1)
In a naive interpreter, this will do one pass rather than two. A smart compiler like GHC can probably optimise away the entire list, getting a tight numeric loop (e.g. https://dl.acm.org/doi/10.1145/1291220.1291199 )
It's not very natural in langages with strict evaluation. Haskell is a good fit because, with lazyness, the order matters less. Same thing goes with purity : what if some side effects hide in "where"?
> Function application uses conventional mathematical notation, e.g. f(a,b) instead of (f a b) as in Haskell.

Thank you for that.

I wonder if it were possible to create a language with the power of Haskell, but with a better, more mathematical-like syntax?
You may want to look into Wolfram Mathematica. It has the syntax f[x,y] and a super extensive standard library, being otherwise very LISPy.
Wolfram has a wild standard library but as a language it is less than elegant.
I remember a distinctly kitchen sink design style in Mathematica language features about 20 years ago, how did it evolve?
Haskell is more versatile: f(a, b) is a function applied to a single tuple, f a b is a function applied to two arguments.

I do not understand the "instead of" in the cited part and it makes me somewhat skeptical (so does the "Py" in the name).

In Haskell, all functions take a single argument.
This "mandatory" currying is an useful and elegant simplification compared to other languages, but in practical terms if we write

      f a b
f has to work as a function of two arguments; that it is also formally interpretable, but not necessarily useful, as a function of one argument is only a nice bonus.
In python, f(a, b) is a function applied to two arguments and f((a, b)) is a function applied to a single tuple.
But is that closer to math notation as claimed in this thread?

https://en.wikipedia.org/wiki/Argument_of_a_function

"For example, the binary function f(x, y) = x + y has two arguments, x and y, in an ordered pair (x, y)."

So, function application to an ordered pair, i.e., a tuple, does not use double parentheses. Also, of course, currying in Python is atrocious.

The lack of parentheses for function arguments in Haskell make currying -- one of its key idioms -- very ergonomic.
Awesome to hear of a new language from Bill Wadge but I’m a bit disappointed. Bill Wadge is of Lucid fame, one of the first dataflow languages. I was hoping for dataflow Python, not functional Python. Although I notice an appearance of the fby (followed by) operator so maybe there is some dataflowyness in here. Will definitely pay close attention to this.
I wonder if the niche of functional language with a lightweight syntax is already being served by F#?
The lisps all have more lightweight syntax than F#. F# is just OCaml for .NET, it is not inherently more lightweight than any other ML.
For a project already invested in the Python ecosystem, F# isn't going to even enter anyone's mind. Think of it as PyFL => Python as F# => C#.
I'm surprised at choosing not to fix the lack of multiple statements in Python's lambda. That grinds my gears, i'm so often denied using lambda in python in places i'd like to because of this limitation.

That said, i do prefer PyFl's lambda syntax.

This is definitely a cool project, i could see myself using this.

(comment deleted)
Nice to see an article on news.ycombinator.com that actually uses the Y combinator. A particularly pleasant definition of it, too:

    Y(a) = g(g) where g(x) = a(x(x));
But I think in PyFL functions are not automatically curried, so that's only applicable to functions of one argument.

I like his syntactic sugar for what would be list comprehensions in Python:

    nprime = not exist p in primes: n mod p == 0 end;
rather than Python's

    nprime = not [p for p in primes if n % p == 0]
but I wonder if the Python/Haskell approach offers more composability.
Is there an explanation of the name?