As I understood special forms in Clojure are building blocks that will be used to construct the rest of the language features. WRT let, as I see let is defined as a macro here. How is it a special form then?
Strictly speaking let is just a front-end to let*, which is a special form. let adds parameter checks and destructuring, but for all other purposes (from a programmer's point of view) it is a special form.
Related
I'd like to preprocess code from another language like so:
Predicate1(X) => Predicate2(Y)
<% (clojure-func "Predicate3" "X" "Y") %>
Basically, what's inside angle brackets gets executed and the emitted string output inserted into the string. I see that there are HTML templating libraries. I'm wondering if I can get by with something like Clojure macros. It is possible that I'm not aware of the benefits provided by a templating library like Fleet or Selmer, and need some guidance.
In the above example I want to create combinations of more expressions:
Predicate3(X_a) => Predicate2(Y)
Predicate3(X_b) => Predicate2(Y)
Ultimately, I do need to keep track of variables of the foreign language. For this purpose pre-processing may be the wrong approach and that instead I'm better off doing complete code-generation.
P.S.: For those of you wondering I'm trying to extend the language of Markov Logic Networks (MLN).
Clojure macros will not help you directly with this. Macros still require expressions to be in essentially Clojure readable syntax with invocations of the form (macro arg1 arg...).
Other Lisps do allow you to extend the readable syntax with reader macros, but Clojure made a decision not to allow them.
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.
As I understand it Clojure does not expose the reader macro table or allow user defined reader macros.
From http://clojure.org/reader:
The read table is currently not accessible to user programs.
I'm just wondering if there is a definitive or explicit statement (presumably from Rich Hickey) stating the rationale for leaving them out of Clojure.
Note I'm not asking if it is a good or bad thing that Clojure lacks user defined reader macros. Just wondering why.
From the link in matt's comments, to quote the answer by Rich Hickey, the author of Clojure:
I am unconvinced that reader macros are needed in Clojure at this
time. They greatly reduce the readability of code that uses them (by
people who otherwise know Clojure), encourage incompatible custom mini-
languages and dialects (vs namespace-partitioned macros), and
complicate loading and evaluation.
To the extent I'm willing to accommodate common needs different from
my own (e.g. regexes), I think many things that would otherwise have
forced people to reader macros may end up in Clojure, where everyone
can benefit from a common approach.
Clojure is arguably a very simple language, and in that simplicity
lies a different kind of power.
I'm going to pass on pursuing this for now,
Rich
Speaking straight there are Tagged Literals that allow you to specify what to do with next form. For example, you can add
{to/u clojure.string/upper-case}
to data_readers.clj (see docs) and write something like this:
testapp.core> #to/u "asd"
"ASD"
but it's not so powerful as full support of reader macros, at least because of
The data reader function is invoked on the form AFTER it has been read as a normal Clojure data structure by the reader.
I found this old log (don't ask me how)
http://clojure-log.n01se.net/date/2008-11-06.html
where there is a discussion with Rich Hickey's thoughts about reader macros.
This might be a stupid question, but since OCaml is not pure and has side effects built-in, what is the use of monads in OCaml?
Monads have nothing to do with purity, except that a pure language without Monads would be almost entirely useless.
In layman's terms, a Monad is just a set of rules that describe how a sequence of steps can be executed. Having a Monad abstraction gives you the ability to define a DSL for executing stuff. A Monad can be built to intelligently handle things like exceptions, ATOMIC rollbacks/commits, retry logic, sleeping between each step, or whatever.
Here are some examples of Monads:
https://wiki.haskell.org/Monad#Interesting_monads
I realize that this list is for Haskell, which is a pure language, but don't let that confuse you.
You don't need to understand category theory to understand what a Monad is, contrary to popular belief. A monad basically has 2 things: (paraphrased from this wikipedia article)
A unit function, defined as (a -> M a), called "return" in Haskell, used to put a value into the context of a Monad.
A binding operation, defined as (M t -> (t -> M u) -> M u), which looks scary but if you look carefully, this is a function that gets invoked between each step of the process, this is where you inject the good stuff.
Depending on the language, there may be more things, but this is the heart of it.
Whilst OCaml supports the standard side-effects provided by most languages, this does not include all possible side-effects. There are a number of effects which OCaml does not provide native support for. Many of these effects can be encoded using Monads. For example,
Concurrency (see Lwt and Async libraries)
Non-deterministic choice
First-class continuations
Ambivalent choice and backtracking
Using more sophisticated representations of computation, such as parameterised monads, even more exotic effects can be encoded. For example,
Polymorphic state
Linear resources
While OCaml allows one to write imperative code it is still functional by its nature, it is used by functional programmers. And we prefer to use persistent data structures and algorithms whenever possible.
What concerning your question, then in particular monads are usefull, for asynchronous computations, e.g., Lwt, Async, where they're used to bind computations (instead of usual way of setting callbacks). Also, monads are used for error handling, instead of exceptions. Also, monads are very helpful in writing parsers, see mparser library. There're also other uses, I enumerated only the most popular.
In general monads just allow you to hide a complex control flow under simple sequential syntax.
This may be a lot more naive than the answer you want but a monad is just a simple abstraction that's useful for structuring computation. It's a little math thing like an equivalence relation (or for people smarter than I am, like a group). Once you learn what they are, you see them everywhere, and they help organize your thinking.
For example pattern matching is a programming language feature that can be added to the clojure language through macros: http://www.brool.com/index.php/pattern-matching-in-clojure
What other language features can be added to the language?
Off the top of my hat I have two examples, but I'm sure there are more.
Contracts programming: https://github.com/fogus/trammel
Declarative logic: https://github.com/jduey/mini-kanren
I think its a stupid question to ask what can be added, what you should ask is what you cant add. Macros allow you to hook into the compiler that mean you can do almost anything.
At the moment you cant add your own syntax to the language. Clojure does not have a user extenseble reader, this means you don't have any reader-macros (http://dorophone.blogspot.com/2008/03/common-lisp-reader-macros-simple.html). This is not because of a technical problem but more a decition by Rich Hickey (the Clojure creator).
What you can not do is implement features that need virtual maschine support like add tail call semantics or goto.
If you want to see some stuff that has been done: Are there any Clojure DSLs?
Note that this list is not 100% up to date.
Edit:
Since you seem you took pattern matching as an example (it is a really good example for the power of macros) you should really look at the match library. Its probebly the best fastest pattern matching library in Clojure. http://vimeo.com/27860102
You can effectively add any language features you like.
This follows from the ability of macros to construct arbitrary code at compile time: as long as you can figure out what code you need to generate in order to implement your language features, it can be achieved with macros.
Some examples I've seen:
Query languages (Korma)
Logic programming (core.logic)
Image synthesis DSL (clisk)
Infix notation for arithmetic
Algebraic manipulation
Declarative definition of realtime data flows (Storm, Aleph)
Music programming (Overtone, Music As Data)
There are a few caveats:
If the feature isn't supported directly by the JVM (e.g. tail call optimisation in the mutually recursive case) then you'll have to emulate it. Not a big deal, but may have some performance impact.
If the feature requires a syntax not supported by the Clojure reader, you'll need to provide your own reader (since Clojure lacks an extensible reader at present). As a result, it's much easier if you stick to Clojure syntax/forms.
If you do anything too unusual / unidiomatic, it probably won't get picked up by others. There is a lot of value in sticking to standard Clojure conventions.
Beware of using macros where they are not needed. Often, just using normal functions (perhaps higher order functions) is sufficient to implement many new language features. The general rule is: "don't use macros unless you absolutely need to".