
Lambdascript – A new pure functional language built on top of Python - baruchel
https://github.com/baruchel/lambdascript
======
baldfat
Maybe I am wrong but I feel like the strength of Python is writing Python and
the arguable weakness of Python is it's speed and concurrency.

Many of these Python built languages seem to flip it around and build on the
weaknesses of Python and not build on Python's strengths.

~~~
sevensor
As a Python programmer, the appeal of the Haskell family seems to be
correctness -- I've come to think of Python as a "surprisingly typed"
language. This particular language looks like it has Haskelly syntax without
the type system. I'd be most interested in the latter; I'd be willing to trade
off performance in some places for stronger ability to reason about types. I
envision a pure, strongly typed language with strict evaluation, that looks
like Python to the rest of my code base.

~~~
nkantar
Have you tried Python's type hints with Mypy, and so you have any thoughts on
it?

~~~
sevensor
I haven't yet -- type annotations in Python 3 still don't seem to have
stabilized. Although I admit I haven't looked too deeply into it, I know a
bunch of new stuff landed in 3.6. The appeal of a library that adds a
functional layer on top of Python is that it partitions "new stuff" from "old
stuff". It seems easier to tear out and reimplement if we screw it up, versus
type annotations diffusing out into the rest of our codebase.

------
guitarbill
Does anybody know a widely used and open source project using literate
programming? (Edit: please include only programs expressed "as a web of ideas"
that Knuth mentions - apparently otherwise it's not literate programming, just
loads of inline documentation?)

From what I've seen, literate programming is great in theory and worse than
useless in practice. It's so far away from reality. I have had the misfortune
of working on a FunnelWeb codebase, and it was one of the most
incomprehensible codebases I've ever seen.

Preprocessing the code is an awful step in any language. Somehow, the "not
documentation" still goes out of date. There are several other problems,
explained at [0] better than I can in a comment.

Specifically about this project: While I enjoy writing blogs in markdown
because of its constraints, reStructuredText (reST) is more
powerful/expressive (by design). Because you can easily express
semantics/relationships, the resulting links in the generated documentation
make the "web" of source code easier to navigate - something Knuth was trying
to do with literate programming.

[0] [http://akkartik.name/post/literate-
programming](http://akkartik.name/post/literate-programming)

~~~
cormacrelf
Corrode, a C to Rust translator. I wouldn't say "widely used", but within the
Rust community it's well known. Literate style seems to work well for code
that's difficult to approach (how would you start building this?), and doesn't
need frequent refactoring.

[https://github.com/jameysharp/corrode/blob/master/src/Langua...](https://github.com/jameysharp/corrode/blob/master/src/Language/Rust/Corrode/C.md)

~~~
guitarbill
I'd say that's a good example. It doesn't use macros, however I do like this
stackoverflow discussion [0] on if Literal Haskell even needs macros, because
it's already a flexible language. Definitely a new perspective.

[0] [https://stackoverflow.com/questions/16869050/is-literate-
pro...](https://stackoverflow.com/questions/16869050/is-literate-programming-
in-haskell-really-literate-programming)

------
nine_k
A propos, [http://coconut-lang.org/](http://coconut-lang.org/) shows a
different approach, easier to integrate with existing Python codebases.

~~~
brightsize
My experience is that it's a joy to use and its lambda and pipe syntax cleans
up my code nicely. Coconut's TCO is handy though pattern-matching is the
killer feature for me. It compiles to a Python 2,3,and PyPy-compatible code.
The language puts a premium on interop with Python, so much so that Python
code IS Coconut code. There's a vim plugin that yields syntax highlighting but
no IDE plugins yet that I'm aware of yet.

------
jerf
You don't make it clear why you're posting this.

If it's just for comment, that's some impressive work. The compiler is fairly
short and is a good demo of how you can do this sort of thing surprisingly
quickly if you know what you are doing.

If you intend this as something a lot of people will use, then I'd express
very serious concerns about building this on top of Python. Python is one of
the slowest languages there is [1]. Putting a mismatching paradigm on top of
it is going to cost you some sort of multiplicative slowdown, which could very
easily be in the 5x range and could even be in the 20x-50x range. Expect
another penalty in memory consumption for what is again already a bit of a
memory-using language. It's not long before you've got a language on your
hands that is 200-500x slower than C, and perhaps more to the point, 100x
slower than Haskell itself. This will make trying to convince anyone else to
use it an uphill battle, because while performance isn't everything (Python is
perfectly suitable for many uses, of course), insufficient performance is a
critical blocker for using it for some project, and performance this bad will
be "insufficient performance" for a _lot_ of projects.

Let me be clear that I am NOT pointing this out as a "criticism" of the
project. If you are doing this to learn or share some fun stuff, this is
irrelevant to you, and let me re-emphasize that you're off to what looks like
a good start! I mean this in the spirit of warning you about what may be your
biggest problem, depending on your unspecified goals, so you can make good
engineering decisions about what to look out for and what to tackle.

One possible solution you could consider is rather than targeting Python AST,
which I _think_ your code is doing?, you might consider targeting the bytecode
directly. While you're still going to experience a certain amount of paradigm
mismatch, you might find this cuts perhaps a 2x out of the multiplicative
slowdown stack, gives you more options that Python directly does, and
especially in the case of PyPy, may give you the option of examining what
bytecode constructs PyPy is better able to optimize and give you some wiggle
room in what you emit that you can exploit.

Even if this is just a learning project you may also find you learn useful
things by doing this; "emitting bytecode" is a popular option nowadays, with
things like LLVM. From emitting bytecode for Python you may even find it not
to be too big a leap to emit native code with LLVM, too. A language that
automatically works natively when code is implemented in pure lambdascript but
transparently interacts with Python would start turning some heads. It's not
hard to imagine potentially getting some speedups over Python. Though that's a
tougher bar to clear; you've got a typesystem to think about at that point.
The code is currently so small and agile it's a good time to start looking at
these issues.

[1]: I no longer believe "languages don't have speeds, only implementations
do". After many years of trying to speed up the many dynamic scripting
languages and generally hitting a wall around 10x-20x slower than C across the
board, I now consider the burden of proof that languages do not at least set
_lower bounds_ on performance to be on someone who can produce a truly fast-
as-C dynamic language interpreter/compiler. (Obligatory LuaJIT callout as the
closest to date.)

~~~
yellowapple
I personally see nothing wrong with writing a prototype in a "slow" language,
especially if speed ain't a priority (yet). Sometimes you just have to get an
initial implementation written in _some_ language, and if that language
happens to be some interpreted language from the 80's, then so be it.

Now, sticking to that language for a _final_ version would be more concerning,
but even that ain't really a dealbreaker; lots of "slow" languages are
perfectly capable of interfacing with "fast" languages through some kind of
FFI (or, at the very least/worst, IPC over some kind of pipe or socket or what
have you). Gradually writing faster implementations as you run into
bottlenecks is a perfectly common and reasonable development approach.

~~~
jerf
"I personally see nothing wrong with writing a prototype in a "slow" language,
especially if speed ain't a priority (yet). "

Neither do I. That's why I conditionalized that point on the intent of the
poster, who as of this writing has not replied to any of these comments.

I wish people would be more clear about their intentions. I have no problem
with any of them, ranging from idly showing off something they did for
discussion to "I intend professionals to drop everything and use this
exclusively", but the feedback appropriate to the various cases along that
range are very different. I don't want to blast a student for not creating
something that Google can base their next 10 years on, but I don't want to
provide someone trying to win over professionals with feedback about their
capitalization of identifiers.

------
35bge57dtjku
Any day now that literate programming is going to hit its hockey stick curve.

------
edraferi
Interesting idea. Given that you can use arbitrary Python expressions as
functions, but that could pollute the functional purity, what stylistic
restrictions to you expect users to self-impose?

~~~
pmontra
About style, why perpetrate those double underscored __atrocities__? I'm sure
there is a better design lurking around in other languages waiting to be
copied. I also don't appreciate _variables.

But kudos for adding tail recursion to a pythonic language. At last.

------
xyproto
Can this be used together with Python for Go? (Grumpy:
[https://github.com/google/grumpy](https://github.com/google/grumpy))

~~~
foxhop
No because:

\- Lambdascript runs on Python3.x

\- Grumpy runs on Python2.7

~~~
xyproto
Can't be hard to port to python 2x, though.

------
lotsoflumens
Maybe 2017 will be the year of "functional fatigue"?

I can only hope I guess ...

~~~
nine_k
Once FP becomes mainstream, and all best parts of the approach are
incorporated in the next great approach, then...

~~~
white-flame
Unfortunately, "going mainstream" usually seems to involve selecting and
running with only the worst parts of any approach. :-P

~~~
nine_k
Cannot agree.

E.g. the best parts of OOP were the ideas of data encapsulation, of
modularity, of interfaces separate from implementations. These live on,
whether you use method dispatch and inheritance or not.

