Fork me on GitHub
#clojure
<
2018-07-01
>
b2berry00:07:50

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.

πŸ‘ 4
matan07:07:40

is that the clojure world's best take at the serverless fad right now? :hugging_face:

b2berry23:07:45

Basically yeah, sure is πŸ˜„

matan06:07:00

I bet they've given it a different opinionated azimuth though πŸ˜‰

matan06:07:22

Might be interesting in the long run. Hope cognitect remains afloat with these commercial projects

Alex Miller (Clojure team)04:07:39

please ask in #datomic and the Datomic team can help you out there

matan07:07:35

Hi, working on a clojure talk for Scala devs here ...

matan07:07:55

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

matan07:07:24

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:

sundarj14:07:03

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

πŸ™ 4
matan14:07:27

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?

matan14:07:37

@sundarj in case you might know ...

sundarj14:07:32

when the compiler sees a form representing a macro, it recursively macroexpands it until it no longer does

πŸ‘ 4
sundarj14:07:27

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)))

sundarj14:07:28

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

mx200008:07:28

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

matan08:07:41

Also @alexmiller care to later on briefly review some slides, for any egregious comments, or points that could have taken a better twist?! ☺️

zclj09:07:09

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.

orestis11:07:14

@matan interesting questions! How about ifs, var declarations etc?

orestis11:07:20

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.

matan11:07:30

@orestis thanks for liking my weird question.

matan11:07:09

wouldn't that parser be entirely CS 101 grade though?

orestis13:07:43

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.

matan14:07:26

Okay, AST parity makes a point, though in this case too, it may seem a parser would be so benign to solve it.....

sundarj14:07:52

@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.

matan14:07:13

@sundarj Nice to know about Elixir πŸ™‚ I'm not finding the relevant thread I suspect

matan14:07:17

What's the downside in Elixir, compared to being fully lispy?

tbaldridge15:07:50

I wouldn’t call Elixir Homoiconic. If you have a parser is that returns an ast, it’s not homoiconic

tbaldridge15:07:46

A better example @matan would be Prolog. It doesn’t use sexprs, but code is data and data is code

sundarj15:07:59

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

βœ”οΈ 4
sundarj15:07:06

another good example is Forth

tbaldridge15:07:31

It has macros, but that’s about it

sundarj21:07:12

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

tbaldridge15:07:00

Ruby does the same

matan16:07:43

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

val_waeselynck07:07:12

Having the same syntax for data literals and data visualization is also pretty useful for the workflow

sundarj16:07:02

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)

matan16:07:19

Thanks @sundarj! I should watch that I guess

matan16:07:52

Actually his talk about thinking in data was rather bland ... but I'll watch anyway

matan16:07:08

How would sending data across the wire relate here?

sundarj16:07:16

@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.

sundarj16:07:52

writing an interpreter for data is much easier than writing an interpreter for a string

matan16:07:55

Hey thanks. Are you into clojure as a hobby?

sundarj17:07:46

i'd certainly like to do it professionally, but at the moment, yeah.

emccue17:07:06

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

emccue17:07:06

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

emccue17:07:08

this isn't really special to homoiconic languages though, its just a benefit of having serializability by default

πŸ™ 4
matan19:07:50

Hey, can someone remind me why and and or had to be macros in clojure? (thus using apply on them being impossible)

bronsa19:07:39

for short circuiting

πŸ‘ 12
bronsa19:07:42

(and false (throw (Exception. "ops"))) would throw if and were a function

bronsa19:07:36

you can use some/`every?` as functional equivalents

matan19:07:35

@bronsa yes I know about some/`every`? but I think the reason might run deeper

matan19:07:59

I mean, this example is a little contrived isn't it?

bronsa19:07:12

not really

bronsa19:07:03

(if (and some-flag (do-some-i/o)) then else)

bronsa19:07:11

is this better?

bronsa19:07:43

anyway, short circuiting is the only reason for and/`or` being macros

matan19:07:07

but, um, couldn't a lisp short-circuit without a macro?

bronsa19:07:19

a lisp (any language really) with lazy evaluation semantics

bronsa19:07:29

but clojure has strict evaluation semantics

bronsa19:07:36

so they need to be macros

bronsa20:07:18

some strict languages implement &&/`||` as both functions and compiler intrinsics with short-circuiting semantics

bronsa20:07:23

like ocaml

bronsa20:07:28

but then you get odd behaviours like

bronsa20:07:35

# 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

bronsa20:07:54

where && only short-circuits when used in certain static ways that the compiler can recognise

matan20:07:18

That's very interesting. Meta-programming also...

matan20:07:41

Thanks. I'll suffice with that for now, as I have to call it a day

matan20:07:49

@bronsa much appreciated!

matan20:07:19

sorry. ... long day

otwieracz20:07:34

Do you have any suggestions regarding SOAP in Clojure?

otwieracz20:07:12

Which library to use, etc. And where to start reading?

seancorfield22:07:55

@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.

seancorfield22:07:57

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.