Can I use monads with clojurescript? - clojure

I know monads are available in clojure, but has anyone verified that they work in clojurescript?

Monads work in clojurescript. The only thing is the way you reference macros in clojurescript [1].
What I did is copy all tools/macro.clj and all the monads.clj code into a big file which I then reference from clojurescript.
It's perhaps not the most elegant way but it works.
You can find the file in https://github.com/cotarmanach/clojurescript-monad-macros
(I copy it in my project and change the namespace to be the one of my project)
[1] See https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure
ClojureScript's macros are written in Clojure, and are referenced via
the require-macros keyword in namespace declarations:
(ns my.namespace (:require-macros [my.macros :as my])) The :as
prefix selector is required in :require-macros. One point of note is
that the code generated by ClojureScript macros must target the
capabilities in ClojureScript.

Monads, the Functional programming method, only require a language with higher order functions and closures. You would need a ClojureScript monad library. Or you can go ahead and write your ClojureScript in a monadic style
EDIT: by "monadic style" I was referring to writing and composing functions that take and return monadic values and implement the three monad laws. There are too many people better qualified to explain monads than I, so I will just link to one of my personal favorite videos on monads.

There is a great port of the Fluokitten Library to ClojureScript by Chris Zheng: https://github.com/purnam/brahmin
Chris has a great post reflecting on Monads as a result of this.
The cats library for Category Theory is also good https://funcool.github.io/cats/latest/
Monads in ClojureScript is alive and well.

Related

Is there an idiomatic alternative to nil-punning in Clojure?

I'm reading some Clojure code at the moment that has a bunch of uninitialised values as nil for a numeric value in a record that gets passed around.
Now lots of the Clojure libraries treat this as idiomatic. Which means that it is an accepted convention.
But it also leads to NullPointerException, because not all the Clojure core functions can handle a nil as input. (Nor should they).
Other languages have the concept of Maybe or Option to proxy the value in the event that it is null, as a way of mitigating the NullPointerException risk. This is possible in Clojure - but not very common.
You can do some tricks with fnil but it doesn't solve every problem.
Another alternative is simply to set the uninitialised value to a symbol like :empty-value to force the user to handle this scenario explicitly in all the handling code. But this isn't really a big step-up from nil - because you don't really discover all the scenarios (in other people's code) until run-time.
My question is: Is there an idiomatic alternative to nil-punning in Clojure?
Not sure if you've read this lispcast post on nil-punning, but I do think it makes a pretty good case for why it's idiomatic and covers various important considerations that I didn't see mentioned in those other SO questions.
Basically, nil is a first-class thing in clojure. Despite its inherent conventional meaning, it is a proper value, and can be treated as such in many contexts, and in a context-dependent way. This makes it more flexible and powerful than null in the host language.
For example, something like this won't even compile in java:
if(null) {
....
}
Where as in clojure, (if nil ...) will work just fine. So there are many situations where you can use nil safely. I'm yet to see a java codebase that isn't littered with code like if(foo != null) { ... everywhere. Perhaps java 8's Optional will change this.
I think where you can run into issues quite easily is in java interop scenarios where you are dealing with actual nulls. A good clojure wrapper library can also help shield you from this in many cases, and its one good reason to prefer one over direct java interop where possible.
In light of this, you may want to re-consider fighting this current. But since you are asking about alternatives, here's one I think is great: prismatic's schema. Schema has a Maybe schema (and many other useful ones as well), and it works quite nicely in many scenarios. The library is quite popular and I have used it with success. FWIW, it is recommended in the recent clojure applied book.
Is there an idiomatic alternative to nil-punning in Clojure?
No. As leeor explains, nil-punning is idiomatic. But it's not as prevalent as in Common Lisp, where (I'm told) an empty list equates to nil.
Clojure used to work this way, but the CL functions that deal with lists correspond to Clojure functions that deal with sequences in general. And these sequences may be lazy, so there is a premium on unifying lazy sequences with others, so that any laziness can be preserved. I think this evolution happened about Clojure 1.2. Rich described it in detail here.
If you want option/maybe types, take a look at the core.typed library. In contrast to Prismatic Schema, this operates at compile time.

State monad vs atom in Clojure

Does state monad make any sense in Clojure? If so, I would appreciate cases where state monad will be more suitable than mutating Clojure atoms via swap!s or reset!s.
You won't bee needing it. But monads are used to build more involved abstractions than plain state. Clojure's core.async's go macro is a state machine and internally it's implemented as a monad. You can watch Tim Baldridge's explanation of it: https://www.youtube.com/watch?v=R3PZMIwXN_g
Monads makes sense if you would prefer to keep the code that way. You can have a (monadic) function which encapsulates state.

Is there an Elixir equivalent for Clojure's (source fn-name)?

Clojure has this handy way to view a function's definition in REPL.
Is there one in Elixir REPL ?
No, there isn't a convenient way yet.
Well, I'm going to post this as an answer, even though it's not the same as "source". In IEX, you can type h function_name to see the documentation for function_name. It's basically Clojure REPL's doc feature. So far, in Elixir, this is good enough for most cases where I want source.

What was the reasoning behind ClojureScript not needing Clojure's defstruct?

defstruct is not supported in ClojureScript - it would appear to be by design. Now it may be that this is effectively a deprecated part of the Clojure language, and the designers of ClojureScript were just hoping everyone had moved on. (But this is my speculation).
My question is: What was the reasoning behind ClojureScript not needing Clojure's defstruct?
defstruct is effectively deprecated in the language, in favor of defrecord. We are supposed to move on in (JVM-based) Clojure, so I would expect Clojurescript to be the same. See the following:
Clojure: data structures: "Note: Most uses of StructMaps would now be better served by records."
ClojureDocs: defstruct comment by steveminer: "Structs are obsolete. Use records instead. See defrecord."
The forthcoming The Joy of Clojure, 2nd ed. (prerelease V9 edition) by Fogus and Houser says "With the advent of defrecord, the need for structs has been nearly eliminated, and therefore structs aren’t covered in this book." (p. 322)
Also note that Programming Clojure, 2nd ed. by Halloway and Bedra covers defrecord but not defstruct (although there are some passing mentions of structures--maybe accidentally left from the 1st ed.).
I guess all the cool people are using defrecord these days. :-)
Alex Miller's answer to "Where should I use defrecord in clojure?" has a nice discussion of advantages (and disadvantages) of defrecord, although he's not, primarily, comparing it with defstruct.

Is there big syntax differences between Clojure and Lisp

I want to learn new language and I thought to start with Lisp. I want to know if I learn Lisp do I also know Clojure ( with minimal effort ), is there big syntax differences between Lisp and Clojure ?
There are not big syntax differences (mostly because Lisp family languages have almost no syntax), but there are certainly differences in other areas. Clojure has a lot of modern programming features particularly suited to high scalability (actors, references, etc) that are not present as such in a "classic" Lisp (such as Common Lisp).
Clojure is an active, well supported dialect of Lisp. If you want to learn a Lisp, you can't really go wrong with Clojure.
You may find more information in the answers to Which Lisp should I learn? .
90% of what you learn while studying your first Lisp will carry over to your next.
I think it's fair to say that if you learn the principles of LISP you will also know the principles of Clojure and vice-versa. They are all rooted in the same philosophy, emphasising things such as:
Code is data. Macros are just normal functions that manipulate code.
Use of S-expressions to represent data and code.
The concept of a list / sequence as a fundamental structure.
Functional programming with first-class functions.
Apart from that, there are lots of differences in syntax, libraries, runtime environments etc. The difference in my view is probably about the same as C# vs. C++ - if you know one well, then the core concepts will be familiar but there are still a lot of fundamental differences.
See this list of ways that Clojure is different from other Lisps
I'm assuming by Lisp you mean Common Lisp, since 'Lisp' itself is more of a family of languages (that includes Clojure) than a single specific language.
There are some syntactical changes in that Clojure was intended to be a more modern Lisp. For instance you can create vectors with []s, maps with {}s, which are not part of Common Lisp. And of course the Java interop inevitably becomes a significant part of Clojure.
Clojure uses vectors as lambda parameters (arguments values), but you can use a macro to write versions of defun and lambda in Common lisp that will look similar . Clojure also has access to Java Object methods and fields using a period (i.e. ".") and the name of the method or field which looks like a normal function call.
(.toString 10) - will call the method toString on number 10 but .toString is not a function. if you try to check the value of .toString it throws an exception that .toString is not a defined symbol.
And also with quasi-quotation (mostly in macros) instead of using a coma for unquote as in Common lisp, Clojure use a tilde.