
Dogelang – A Python with Haskell Syntax - pcr910303
http://pyos.github.io/dg/
======
thedataangel
Haskell's syntax without Haskell's type system sounds like a nightmare. The
type system is what makes me at least vaguely confident that the
incomprehensible string of symbols that make up a good chunk of Haskell
expressions are at least close to being correct.

(And to be clear: I use Haskell professionally and love it - but the syntax is
_not_ why most people use Haskell).

~~~
laughinghan
Did the tagline "Slow. Stupid. Absolutely adorable." not clue you in that this
is a joke?

~~~
icedchai
The name alone should be enough.

~~~
manthideaal
Why?, not a native English speaker, I looked up doge and it has no meaning,
any tips for other meaning?

~~~
DoreenMichele
It's a meme:

[https://en.wikipedia.org/wiki/Doge_(meme)](https://en.wikipedia.org/wiki/Doge_\(meme\))

------
makapuf
Id much rather have python syntax and Haskell semantic to get good parts of
both!

~~~
amelius
One problem with Python's syntax, though, is that you can't have anonymous
lambdas which span more than one line (unless perhaps you start using escapes,
but that would miss the point).

~~~
progval
I'm not sure what you mean by escapes, but you can use parentheses as block
delimiters, "and" and "or" as a semicolon, and ternary operator for
conditionals

    
    
        >>> f = lambda x: (
        ...   (
        ...     print('a') or
        ...     print('b')
        ...   ) if x % 2
        ...   else (
        ...     print('c') or
        ...     print('d')
        ...   )
        ... )
        >>> f(42)
        c
        d
        >>> f(43)
        a
        b

~~~
samatman
My God, man. My eyes!

That is strikingly hideous. After such knowledge, what forgiveness?

~~~
saagarjha
A language that actually cares about functional programming.

~~~
cle
Oh please. You can "do" functional programming just fine in Python. If it's
longer than a line, give it a name. It's not hard and it makes the code more
readable and easier to maintain.

~~~
saagarjha
I do most of my work in multi-paradigm languages–so it's not like they're
specifically designed around the ergonomics of working with functional
programming–but Python is probably the worst language that I have used that
could reasonably say that it supports this style of work. It's like it
actively _tries_ to make things strange and annoying to convince you to use
other constructs (such as list comprehensions). Why can't I have a multiline
lambda (…some things have no need for a name)? Why are all the functional
methods free functions that take the list as the second parameter? Why was
reduce arbitrarily excised from the list of built-in functions and put inside
functools? Why can't I use a member function or operators as parameters
without hacks like operators.__{operator_thats_a_reserved_word}__? Why do all
the Python 3 functions return generators by default, when Python never really
cared much about performance in the first place? It's just a death by a
thousand cuts that always makes me regret even trying to do functional
programming, and deep down I actually think the Python authors just don't want
you do be doing it because they think it would lead to what they believe is
difficult-to-understand code. Honestly, I think _even C++_ has better
functional programming constructs than Python, even with its ugly-looking
lambdas and lack of chaining, because <algorithm>'s extensiveness makes up for
some of the language's warts.

~~~
amelius
In defense of Python, at least it supports closures that easily refer to
variables higher up in the stack, whereas in C++ you always have to think
about the lifetime of variables. Your other points I agree with.

------
pizza
Is there a Python with Haskell syntax (or at least, much less verbose than
regular Python..) that can have little a Haskell static typing, as a treat?

~~~
cyorir
Nothing comes to mind. Most attempts to introduce static typing into Python
only do that, and not much more. Seq is an example:

[https://github.com/seq-lang/seq](https://github.com/seq-lang/seq)

I think you might be interested in looking at multi-paradigm languages that
use static/inferred typing and combine the functional and imperative
paradigms. Some worth taking a look at might be OCaml, Nim, and F Sharp. Nim
leans more towards Python, OCaml and F# lean more towards Haskell.

[https://en.wikipedia.org/wiki/OCaml](https://en.wikipedia.org/wiki/OCaml)

[https://en.wikipedia.org/wiki/Nim_(programming_language)](https://en.wikipedia.org/wiki/Nim_\(programming_language\))

[https://en.wikipedia.org/wiki/F_Sharp_(programming_language)](https://en.wikipedia.org/wiki/F_Sharp_\(programming_language\))

~~~
abhijat
Ocaml is really good with nice tooling like merlin. Compiles to native as
well. There's reasonml for people who favour js syntax but I have come to like
ocaml syntax.

------
misnome
On a serious note, I've long wondered what python would feel like with
haskell-style "whitespace" to call/partially call functions. It feels like it
wouldn't be super difficult to get working; as far as I can think of
"identifier ws identifier" is always currently a syntax error? Maybe a toy
python project someday...

~~~
koenigdavidmj
Python has enough vararg functions to make this not doable without coming up
with some special-case syntax. There's a reason you don't have varargs in the
Haskell world--currying isn't a special case, but rather happens any time you
have multiple arguments. A three-argument function with type (A -> B -> C ->
D) is actually syntactic sugar for a function that takes an A and returns...

a function that takes a B and returns...

a function that takes a C and returns...

a value of type D.

This is determinable by just looking at the number of arguments provided. But
a variadic function, in a world with currying, would be a function that takes
an argument, and returns...well, it might be a function to take another
argument, and it might be the actual computation.

Even if we didn't have currying, we can't just use whitespace in a Python-like
language. We don't know if (print) is actually a function call, or just
referencing the function object (perhaps to pass it to 'map' or something).
Your syntax needs to distinguish between those two cases.

~~~
eru
There are varargs in Haskell, but they aren't as natural as in Python; and
usually rely on various amounts of type level trickery.

Implementing a vararg printf in Haskell is a popular enough exercise.

A relatively common examples in practice is the testing library QuickCheck:
your properties (ie tests) can take any number of arguments that the library
fills with samples inputs.

------
yellowapple
All the performance of Python with all of the readability of Haskell ;)

~~~
ferzul
what's <$> so unreadable <*> about haskell?

~~~
wwright
The learning curve is pretty intense, but I do want to say that the operators
you use here are actually _pretty great_ for readability after you learn them.

I don’t know if that makes them worthwhile, but I always find them a breath of
fresh air.

~~~
eru
A lot of Haskell's more controversial constructs are about being able to hide
plumbing.

Applicative plumbing is especially easy in structure, so removing it from you
doesn't hide any complexity from the experience programmer. It's easy to
reconstruct the plumbing on the fly in your mind, if you want to reason about
it.

Other tools like lenses or arrows take a lot longer for a lot of people to
internalize like that.

------
smegma2
I've been wanting this for a while, mainly because I often find myself writing
long function composition chains that end up being a mess of parentheses.
Python is good at encouraging functional style but sometimes it ends up being
too much to be readable with the normal syntax.

~~~
dzsekijo
Python is as good at encouraging functional style as a massive arsenal of
weapons of mass destruction is good at encouraging world peace.

------
thanatropism
I'm a big fan/proponent of Hy ([http://hylang.org](http://hylang.org)), a Lisp
built onto Python. Even going to the somewhat irresponsible extent of using it
in production!

------
jhbadger
Another language that is similar, but with more an ML syntax is MLite
([https://www.t3x.org/mlite/index.html](https://www.t3x.org/mlite/index.html)).
Like this, it's an interpreter with dynamic typing, and probably not that
useful, but it is fun to play around with functional programming with.

------
kbumsik
> A programming language that compiles to CPython bytecode, much like Scala
> compiles to JVM's.

I'm wondering if the CPython bytescode is stable though. Is the Python
bytecode spec managed independently from the language version (like JVM) so
this kind of approach won't break when a new Python is released?

------
anonsivalley652
I'm not sure what's funnier: that it exists or that some people still haven't
heard of Poe's law. Or did a sense of humor pervasively roll on its back,
cross its arms and legs, and replace their eyes for X's?

------
jchook
Reminds a bit of Clio lang [0].

Clio transpiles to JavaScript and appears to target microservices or
serverless architecture.

[https://clio-lang.org/](https://clio-lang.org/)

------
krick
So, the worst of two worlds? Nice. Dogelang indeed.

------
jefurii
How about a Rust or a Go with Python syntax?

~~~
steveklabnik
[https://github.com/mystor/slag](https://github.com/mystor/slag) (Won’t
actually work today)

------
rossdavidh
Nice, but after it compiles to CPython bytecode, it really ought to transpile
to Javascript.

~~~
cyorir
PureScript already has the Haskell -> Javascript niche covered:

[https://en.wikipedia.org/wiki/PureScript](https://en.wikipedia.org/wiki/PureScript)

~~~
ghostwriter
Why using a separate language if GHCJS is already good enough?

~~~
cyorir
According to the creator of PureScript:

"Solutions at the time included various attempts to compile Haskell to
JavaScript while preserving its semantics (Fay, Haste, GHCJS), but I was
interested to see how successful I could be by approaching the problem from
the other side - attempting to keep the semantics of JavaScript, while
enjoying the syntax and type system of a language like Haskell."

[https://leanpub.com/purescript/read#leanpub-auto-about-
the-a...](https://leanpub.com/purescript/read#leanpub-auto-about-the-author)

~~~
ghostwriter
It's a good reason for the author of the language, and for anyone who's
interested in designing programming languages. However, I often wonder why
people in the industry promote it as a great choice for developers who are
looking for a "Haskell for frontend", instead of recommending GHCJS. I do
understand why Elm is recommended instead of Haskell for simplicity reasons,
but PureScript is neither simpler nor (presumably, if I'm not missing
something) conceptually more valuable (i.e. bringing refreshingly new ideas)
than GHC Haskell.

~~~
wwright
Purescript does have algebraic effects and row polymorphism generally, which
Haskell does not AFAIK (I don’t do as much Haskell as I would like so I may be
wrong.)

~~~
ghostwriter
Algebraic effects are not part of the language implementation, but there are
libraries like fused-effects[1] that implement them. Row polymorphism has been
proposed a few years ago [2], but as with any community effort, the timeline
and possibility of the actual implementation depends on the amount of
attention put into it instead of some other (probably important, too) work.

[1]: [https://github.com/fused-effects/fused-
effects](https://github.com/fused-effects/fused-effects) [2]:
[https://github.com/ghc-proposals/ghc-
proposals/pull/180](https://github.com/ghc-proposals/ghc-proposals/pull/180)

------
bishalb
I wish they used the famous Doge meme image for the mascot.

------
AzzieElbab
super cool. if anything else it exposes haskellers sense of humor

------
whoisthemachine
Finally, I have found my language.

