Fork me on GitHub
#beginners
<
2018-09-24
>
noisesmith00:09:06

putting a function in a set is rarely useful

quadron00:09:40

I know, that set is for me, not for the interpreter

noisesmith00:09:58

what does the function being in the set do?

quadron00:09:21

let's say I have a little file system with a shell on top

quadron00:09:28

those are the shell commands

noisesmith00:09:32

btw (fn [name] (:mkdir name)) can be replaced by :mkdir - as a function, :mkdir does the same thing given one argument

noisesmith00:09:58

what I'm saying is the equality of any function to the function in the set fails, so I don't understand what it does

noisesmith00:09:21

user=> (= (fn [x] :OK) (fn [x] :OK))
false

quadron00:09:14

forget about the set

noisesmith00:09:22

and I also don't know how any of this relates to pattern matching

andy.fingerhut00:09:23

Clojure destructuring has some features in common with pattern matching in other languages. In some languages, the compiler will look at pattern matching code and use information about the types of the values you are doing pattern matching on, and give an error if you left out any cases. Clojure doesn't have anything like that, and I believe that aspect is what Rich objects to, since it can make additions to data structures in one part of the code require changes through a system.

andy.fingerhut00:09:39

(I do not speak for Rich -- I am guessing based on listening to many of his talks.)

noisesmith00:09:14

another argument he makes is that pattern matching code is brittle, you need to change all the consumers when you extend the input

lilactown00:09:13

@veix.q5 for a pattern like a specification of commands, something like defmulti is much more well suited

noisesmith00:09:24

(in that case he argues that multimethods and protocols are more flexible as a design - extension happens from the outside instead of the call site)

☝️ 4
andy.fingerhut00:09:09

The aspects of pattern matching in other languages (that I am aware of, at least -- haven't used them myself) that Clojure destructuring shares is the ability to pull apart a compound data structure and give local names to pieces of it.

lilactown00:09:00

destructuring and pattern matching are not the same IMO. sometimes the syntax is coupled but they are not really related conceptually

lilactown00:09:31

e.g. Elixir’s syntax for pattern matching also destructures

quadron00:09:42

does the above make sense?

lilactown00:09:46

yeah. so you expect to write your commands like: (handler [:cd "/users/quadron/"]) ?

quadron00:09:45

say in the sub-repl I type: :cd /usr/lib/

andy.fingerhut00:09:11

I am not aware of an existing REPL that would take a line like that as input and call your multi method. You could of course create your own REPL without a lot of trouble that would do so.

quadron00:09:27

@lilactown would you please elaborate on how destructuring and pattern matching differ?

quadron00:09:15

btw the above commands are supposed to be executed in the shell of a particular application.

lilactown00:09:18

Destructuring is a way of binding values that are in a collection Pattern matching is a way of controlling the flow of a program by relating branches to sets of types or values

andy.fingerhut00:09:35

I wouldn't be surprised if the details of how pattern matching behaves differs across programming languages. The kind I was comparing/contrasting to above is what I know about pattern matching in Haskell. Are you thinking of a particular programming language's flavor of pattern matching other than that?

quadron00:09:04

my limited mind associates pattern matching in haskell to multimethods+destructuring in clojure

mfikes00:09:43

There’s also this as a library: https://github.com/clojure/core.match

andy.fingerhut00:09:31

Ah, yes. Clojure destructuring has nothing in comping with selecting one of several cases in your program's control flow. Pattern matching that I have seen is a combination of a switch/case statement for control flow based on the actual type of a value, plus optional destructuring for each case.

quadron00:09:32

@mfikes I understand core.match is frowned upon?!

mfikes00:09:36

Interesting sentiment 🙂

andy.fingerhut00:09:46

I am confused by my last comment -- trying to remember what I actually tried to type now 🙂

seancorfield00:09:49

@veix.q5 In Haskell you'd have patterns for, say, an empty list and a list with a head and a tail. In Clojure (let [[x & xs] ...] ...) destructuring will match both an empty list and a non-empty list. That's a fundamental way that pattern matching (in Haskell) is very different to destructuring.

👍 4
✔️ 4
andy.fingerhut00:09:43

There might be some developers who have used core.match and don't want to use it again, perhaps, but not sure there is any kind of widely held belief like that.

mfikes00:09:25

It is certainly true that core.match is not a prevalently used library.

quadron00:09:05

for the record, I found the following approach more elegant: https://github.com/dundalek/closh/blob/master/src/closh/zero/parser.cljc

quadron00:09:50

spec conforming

Mike C15:09:42

I'm trying to get up and running with ClojureScript / figwheel main / Cider so that I can have a cljs repl in Emacs just as I would when working on Clojure. However, when I make a new project (`lein new figwheel-main cider-test`) and then open the new, unedited core.cljs in Emacs and run cider-jack-in-cljs I get a 3 exceptions about unvalid tokens and unmatched delimiters

Mike C15:09:23

I know the core.cljs file is OK because a) it's untouched after being generated from the lein figwheel-main template and b) I can run lein fig:build from the terminal and it works fine

bhauman15:09:24

type “dev”

bhauman15:09:16

@clarkema the common problem here is that folks don’t type the name of their build at the prompt

Mike C15:09:20

that's what I get for blindly accepting the defaults

Mike C15:09:34

It suggested :dev and I just went with it

Mike C15:09:38

thanks 🙂

bhauman15:09:46

everyone is having this problem

bhauman15:09:27

@richiardiandrea is anyone looking at this?

clark15:09:34

just got hit by this one as well 😆

Mario C.16:09:11

Hello I am having some issue with making a POST using CLJS-Ajax

(POST "/endpoint"
             {:format :json
              :params {:body (js/JSON.stringify (clj->js params))}
              :error-handler (fn [e] (log "Error in async-command-c") (js/alert e)))
              :handler (fn [r] (put! ch r))})

Mario C.16:09:55

This is my server handler

(POST "/endpoint" body
    (println (body :body))
    (execute-l body))
`

Mario C.16:09:06

My body ends up being this object literal

Mario C.16:09:14

#object[org.eclipse.jetty.server.HttpInput 0x8467c35 org.eclipse.jetty.server.HttpInput@8467c35]

Mario C.16:09:34

This is after upgrading cljs-ajax from 0.1.3 to 0.7.3

noisesmith16:09:16

that HttpInput is something you can slurp or otherwise read from, if you had a normal ring middleware stack it would do that for you

Mario C.21:09:40

@U051SS2EU If I am using undertow and getting an undertow inputstream in the body of the request. Can I still slurp it?

Mario C.21:09:48

It doesn't seem like I can

noisesmith17:09:18

I'm not familiar with undertow - it might be the case it was already consumed and the data consumed is somewhere else in the request map

Mario C.16:09:28

wrap-json-body seems like it would do the trick

Mario C.18:09:02

I am getting nil for my body. But it is defined in the request. Any idea what I am doing wrong?

(POST "/endpoint" [body :as request]
    (println body)
    (execute-l body))

deliciousowl18:09:00

I think

[{body :body} request]
?

Mario C.18:09:39

I got it to work with {:keys [body]}

Mario C.18:09:02

Here is the request output {... :query-string nil, :body {:body {"example":"test-1-2-3"}}, ...}

quadron19:09:07

why does datomic adopt a schema for the database? this seems to go against the clojure mindset.

quadron19:09:40

is it for performance?

donaldball19:09:45

There is a #datomic room in which this question may be better asked, but I would observe that datomic needs to know the cardinality of an attribute in order to allow or prohibit duplicate e/a values, and it needs to know the type in order to sort the v indexes correctly. I also wouldn’t really say that the clojure mindset opposes types for values; maybe more that it doesn’t see significant value in mandatory compile-type checking.

quadron19:09:14

@donaldball why not spec then?

donaldball19:09:27

I’m not sure what you mean? spec came after datomic, fwiw, but if you squint, it’s possible to perceive spec as generalization of datomic’s schema

quadron19:09:25

@donaldball would you say that if datomic were to be redesigned it would take specs instead of types?

donaldball19:09:47

Ha, that question is far above my pay grade. I guess I might not be surprised to see a future version of datomic that can derive schema from (some well-defined subset of) specs and enforce storage-time spec validation of values. But you can already get basically there if you want using txn fns, and Cognitect is famously cautious about changing features, so I dunno. ¯\(ツ)

Alex Miller (Clojure team)19:09:54

none of that makes any sense to me. the goals of Datomic and spec are different, spec is not a generalization of Datomic’s schema at all, and I think there is little chance Datomic would use spec in that way.

Alex Miller (Clojure team)19:09:16

but I am not on the Datomic team and don’t speak for them :)

donaldball20:09:31

Mmm, definitely listen to Alex, though both datomic schema and spec have the notion of associating type metadata with a (namespaced) keyword… it seems to me that they’re playing in the same end of the pool

quadron20:09:35

@alexmiller what is the goal of datomic? my concept is that spec is a language about data and a perfect fit where types are used in datomic.

Alex Miller (Clojure team)20:09:49

datomic inherently has to deal with storage and indexing and thus uses a small fixed set of known types

✔️ 4
Alex Miller (Clojure team)20:09:04

spec is about predicates which is an open system

Alex Miller (Clojure team)20:09:37

these are (intentionally) very different ideas

quadron20:09:09

How does datomic enforce properties for acceptable data?

cfleming10:09:16

@UCEKLQ24T I didn’t sorry but I’ll look at it before the next EAP. I’ve filed this so I don’t forget: https://github.com/cursive-ide/cursive/issues/2054

cfleming10:09:56

One thing to check - the symbol you’re trying to evaluate is actually instantiation-hash, right? i.e. with a - rather than a _

bmcferren13:09:54

it is an underscore _ I use underscore in order to quickly discern variables from functions and I use underscores instead of hyphens out of scorn from bugs Id experienced earlier in the angular side of my career. I just checked another variable that doesn't involve an underscore and the same issue arises

bmcferren13:09:59

I did notice that (+ 1 1) does evaluate

bmcferren13:09:14

so it seems related to variables and scope

quadron20:09:13

say the db has an email identity, that has to satisfy email spec

dpsutton20:09:26

you can read the types that datomic knows about here: https://docs.datomic.com/on-prem/schema.html.

asilverman22:09:08

Hi everyone, I just discovered Clojure as a language and am looking for some good guidance on how to learn it. I am mostly a c style developer and would really appreciate leveraging some of your experiences.

quadron23:09:50

why can't I put nil on a channel? :thinking_face:

Alex Miller (Clojure team)23:09:56

channels are for conveying values

Alex Miller (Clojure team)23:09:07

nil is the absence of a value