This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-07-01
Channels
- # beginners (134)
- # boot (4)
- # cider (11)
- # cljs-dev (3)
- # cljsrn (10)
- # clojure (85)
- # clojure-dev (10)
- # clojure-spec (17)
- # clojure-uk (14)
- # clojurescript (19)
- # copenhagen-clojurians (1)
- # data-science (15)
- # datascript (3)
- # datomic (3)
- # fulcro (1)
- # graphql (3)
- # heroku (1)
- # hoplon (1)
- # leiningen (2)
- # nrepl (11)
- # om-next (1)
- # onyx (35)
- # reitit (3)
- # shadow-cljs (43)
- # spacemacs (2)
- # specter (1)
- # test-check (10)
- # tools-deps (1)
- # vim (1)
Anyone playing with IONS? I’ve found myself pretty far down the road with set-up and deployment but finding myself in uncharted waters with very little to go on deploying this web app. I’m beyond simple tutorial fodder.
Might be interesting in the long run. Hope cognitect remains afloat with these commercial projects
please ask in #datomic and the Datomic team can help you out there
Trying to think of a crisp example for why prefix notation is necessary for homoiconicity.... there's bound to be some cognitive resistance to the lisp syntax for some of the crowd.. that dissolves as much as rationale is provided
Anyone care to demonstrate how couldn't we write func(args)
and have the interpreter turn it into (func args)
without running into trouble? :grinning_face_with_one_large_and_one_small_eye:
it's not really prefix notation that's required (you could envision a lisp that does (1 + 1)
instead); prefix notation just makes everything more simple and consistent
it's the fact that in a lisp, the code you write is directly represented by data structures. it's certainly possible to have some of the features of homoiconicity without it [1], but lisps make it effortless - there is no difference between what you write, and what the compiler sees, so there's no extra cognitive overhead of a translation step
[1] see elixir:
https://elixir-lang.org/getting-started/meta/quote-and-unquote.html
https://elixir-lang.org/getting-started/meta/macros.html
note how different the syntax is to its internal representation, while in lisps (+ 1 1)
is exactly what it appears to be.
this means that macros in elixir essentially have to go through the quote/unquote dance, while in Clojure, syntax-quote/unquote are just for convenience, and it's still easy to write macros without them: just use normal Clojure functions that return data!
for example, this macro: https://gist.github.com/noisesmith/3490f2d3ed98e294e033b002bc2de178
this article is a good explanation: http://vvvvalvalval.github.io/posts/2018-01-06-so-yeah-about-clojures-syntax.html
actually, how are macros evaluated? does the 'compiler' endlessly apply macros until the expression no longer matches any macro name? or does it have a weaker iteration algorithm that only considers macros from each package once?
when the compiler sees a form representing a macro, it recursively macroexpands it until it no longer does
boot.user=> (defmacro my-when [test & body] (list* 'when test body))
#'boot.user/my-when
boot.user=> (macroexpand-1 '(my-when true (println 42)))
(when true (println 42))
boot.user=> (macroexpand-1 *1)
(if true (do (println 42)))
boot.user=> (macroexpand '(my-when true (println 42)))
(if true (do (println 42)))
boot.user=> (source macroexpand)
(defn macroexpand
"Repeatedly calls macroexpand-1 on form until it no longer
represents a macro form, then returns it. Note neither
macroexpand-1 nor macroexpand expand macros in subforms."
{:added "1.0"
:static true}
[form]
(let [ex (macroexpand-1 form)]
(if (identical? ex form)
form
(macroexpand ex))))
nil
I am trying to connect to remote nrepl server, I am running OSX and server is ubuntu. How can I use ssh port forwarding to make it work? ✗ ssh -L 7000:theserver:7000 localhost ssh: connect to host localhost port 22: Connection refused
Also @alexmiller care to later on briefly review some slides, for any egregious comments, or points that could have taken a better twist?! ☺️
I have a function that returns
`[(ns/some-symbol ~params)]
for later evaluation. Now I want to move the creation of the function into a macro. But I struggle with creating a macro that should include a backtick as part of its output. Can I do that or do I need to solve it some other way?
So the some-symbol
should be constructed when the macro runs but the params
should be evaluated in run-time.I think (without having much experience so far) is that, sure, the compiler could turn infix to prefix, but then you need a parser, then your editor also needs to have a parser if you want to send forms to a repl.
How would macros work? The cool thing about S expressions are that your macro is the same form as my macro is the same as core stuff like if.
Okay, AST parity makes a point, though in this case too, it may seem a parser would be so benign to solve it.....
@matan see my comments in the thread above. parsing non-lispy syntax into data is what Elixir does, so it's certainly possible, but is different to what lisps do.
I wouldn’t call Elixir Homoiconic. If you have a parser is that returns an ast, it’s not homoiconic
A better example @matan would be Prolog. It doesn’t use sexprs, but code is data and data is code
Good read http://www.petecorey.com/blog/2017/08/07/what-if-elixir-were-homoiconic/
i didn't intend to suggest that elixir was homoiconic, just that it had some of the features typically attributed to homoiconicity. sorry if that wasn't clear
It has macros, but that’s about it
hmm, i had assumed that the data structures created by quote
in Elixir could be manipulated at runtime like they can in lisps, but i suppose that might not be the case (i've no experience with Elixir either way), in which case they really are just compile-time ASTs like any other language, and are thus even less powerful than i had thought.
cc @matan
Ruby does the same
BTW, aside the metaprogramming does the homoiconicity provide any added value? I mean it's not that we see too many tools that leverage the metaprogramming for higher development throughput, at least I'm not seeing them.. and it's a generally good advice to keep at arms length from writing a lot of macros
Having the same syntax for data literals and data visualization is also pretty useful for the workflow
there's plenty: paredit, parinfer, sending forms to a repl from the editor, sending code across the wire (like with the socket repl and nrepl)
here's a talk about it: https://www.youtube.com/watch?v=o7zyGMcav3c
@matan in any language, you can send code across the wire as a big string, but strings are opaque and hard to work with, so all you can really do is evaluate that string wholesale, which is why people use a separate data format like JSON. in (e.g.) lisps, you can send the language's code directly across the wire as data, and then manipulate, transform, or interpret it however you like (including evaluating it wholesale). you can also send individual expressions across the wire, which you can't really do in other languages.
for example, in Fulcro and Om Next, you write mutations for your application's state in data that looks like code, so [(shopping-cart/add-item! {:id 26, :quantity 4})]
. that gets interpreted locally, but can also be sent to the server as a string, turned into data with clojure.edn/read-string
, and interpreted there as well. in another language, you might have to send that as a string, and then call eval
on it without being able to do anything else to it, or use JSON instead.
writing an interpreter for data is much easier than writing an interpreter for a string
On the data subject, I see homoiconicity help me when developing prototypes without databases. I just dump whatever I am working with into a text file and read it back in with clojure.edn/read-string
Similar to python's pickle
or java's now depreciated Serialization
, having the ability to save the data in your program without much hassle is extremely useful
this isn't really special to homoiconic languages though, its just a benefit of having serializability by default
Hey, can someone remind me why and
and or
had to be macros in clojure? (thus using apply
on them being impossible)
some strict languages implement &&
/`||` as both functions and compiler intrinsics with short-circuiting semantics
# false && (print_endline "oops"; true);;
- : bool = false
# (&&) false (print_endline "oops"; true);;
- : bool = false
# let f = (&&) in f false (print_endline "oops"; true);;
oops
- : bool = false
where &&
only short-circuits when used in certain static ways that the compiler can recognise
@slawek098 My recommendation is to depend on Axis 2 (or Axis 1) libraries and use Java interop. I went down this path years ago and never found a satisfactory Clojure wrapper but using Axis directly from Clojure isn't too badly so that's what we ended up doing.
We used wsdl2java
to create Java stubs, compiled those into a JAR, put it in our Archiva repo and "forgot about it" and then it was just a little bit of interop from Clojure.