Fork me on GitHub
#clojure
<
2020-02-26
>
tstout00:02:15

I have an esoteric question. While discussing eval-ing the current form in a repl, with a co-worker, they asked why is it called a form? This question has bothered me for a long time as well. I assumed it was either from McCarthy or Church's work. However, I have struggled to find the origin of this term in the context of lisp.

andy.fingerhut00:02:25

I have a copy of the Lisp 1.5 programmer's manual, 2nd ed, 15th printing., dated 1985, that uses 'special forms' as part of its terminology. Co-authored by John McCarthy

andy.fingerhut01:02:21

This 1960 paper by McCarthy mentions the distinction between 'function' and 'form' with a reference to an earlier paper by Church: http://www-formal.stanford.edu/jmc/recursive.pdf

benoit01:02:29

Good question 🙂 I wouldn't be surprised if it came from logic https://en.wikipedia.org/wiki/Logical_form

noprompt04:02:33

Normal form also comes to mind and has been around for a long time too. https://en.m.wikipedia.org/wiki/Canonical_form

hiredman00:02:32

https://www.merriam-webster.com/dictionary/form has things like "a mathematical expression of a particular type" or "pattern, schema"

hiredman00:02:45

compare to formula where fortran is a portmanteau of formula and translation

hindol08:02:20

Seems to me (. Math (random)) is just another way of calling (Math/random).

reborg08:02:26

Yes, is syntax sugaring (macroexpand '(Math/random)) => (. Math random)

mavbozo08:02:08

thanks, I thought it was a function call

reborg08:02:49

the round parenthesis are optional (I think their reason is to make the interop with arguments more readable)

erwinrooijakkers13:02:56

lein-git-down gives an error when trying to pull from private repo with the following config:

(defproject private.config-server "0.1.0-SNAPSHOT"
  ...
  :dependencies [[mq-lib "02d8430963ba5bdc144089f5a62d5aaba8334e24"]]

  :repositories [["private-bitbucket" {:url "" :protocol :ssh}]]
  :git-down {mq-lib {:coordinates private/mq-lib}}

  :plugins [[reifyhealth/lein-git-down "0.3.5"]]
  :main ^:skip-aot nl.private.config-server.main
  :resource-paths ["resources" "resources/private/config_server" "target/resources"]
  :prep-tasks     ["javac" "compile" ["run" ":duct/compiler"]]
  :middleware     [lein-duct.plugin/middleware
                   lein-git-down.plugin/inject-properties]
  :profiles
  {:dev  [:project/dev :profiles/dev]
   :repl {:prep-tasks   ^:replace ["javac" "compile"]
          :repl-options {:init-ns user}}
   :uberjar {:aot :all
             ...
             :resource-paths ["src"]}
   :profiles/dev {}
   :project/dev  {:source-paths   ["dev/src"]
                  :resource-paths ["dev/resources"]
                  :dependencies   [[integrant/repl "0.3.1"]
                                   [eftest "0.5.7"]
                                   [kerodon "0.9.0"]
                                   [hawk "0.2.11"]]}})

vemv14:02:19

lein-git-down maintainers are responsive over github

erwinrooijakkers13:02:30

Error:

$ lein deps
Retrieving mq-lib/mq-lib/02d8430963ba5bdc144089f5a62d5aaba8334e24/mq-lib-02d8430963ba5bdc144089f5a62d5aaba8334e24.pom from private-bitbucket
Retrieving mq-lib/mq-lib/02d8430963ba5bdc144089f5a62d5aaba8334e24/mq-lib-02d8430963ba5bdc144089f5a62d5aaba8334e24.jar from private-bitbucket
Could not find artifact mq-lib:mq-lib:jar:02d8430963ba5bdc144089f5a62d5aaba8334e24 in central ()
Could not find artifact mq-lib:mq-lib:jar:02d8430963ba5bdc144089f5a62d5aaba8334e24 in clojars ()
Could not transfer artifact mq-lib:mq-lib:jar:02d8430963ba5bdc144089f5a62d5aaba8334e24 from/to private-bitbucket (): @bitbucket.org/private/mq-lib: Auth fail
Could not transfer artifact mq-lib:mq-lib:pom:02d8430963ba5bdc144089f5a62d5aaba8334e24 from/to private-bitbucket (): @bitbucket.org/private/mq-lib: Auth fail
This could be due to a typo in :dependencies, file system permissions, or network issues.
If you are behind a proxy, try setting the 'http_proxy' environment variable.

erwinrooijakkers13:02:22

Any idea how to fix?

Alex Miller (Clojure team)13:02:51

private ssh repos will use ssh-agent so that's what you need to debug - 1) is it running? 2) does it have your identity - ssh add -l should list it

erwinrooijakkers13:02:51

Thanks!

$ ssh-add -l
The agent has no identities.

dharrigan13:02:20

One thing I would recommend is to use something like . I've been using it for years and is super super handy for doing ssh work.

erwinrooijakkers13:02:08

$ ssh-add ~/.ssh/id_rsa
Identity added: id_rsa (id_rsa)
Fixed it! Thanks

Axel Svensson14:02:50

Question: Is the following expected?

(clojure.string/split "/a/b/c///" #"/") => ["" "a" "b" "c"]
     (clojure.string/split "/a/b/c///" #"/" 100) => ["" "a" "b" "c" "" "" ""]

Alex Miller (Clojure team)14:02:09

yes, there are some tickets about this https://clojure.atlassian.net/browse/CLJ-1857 - some changes folded into https://clojure.atlassian.net/browse/CLJ-1360 (not yet applied)

👍 4
Crispin14:02:52

pass -1 as the final arg to not cull the empty strings. This behavior comes from java IIRC.

👍 4
p-himik14:02:35

The page at https://clojure.org/reference/reader#_literals says: "[Keywords] cannot contain '.' in the name part" The Rich's post at https://groups.google.com/forum/#!msg/clojure/CCuIp_bZ-ZM/9yP41gt7wuoJ (from 11/24/08) says: "As far as '.', that restriction has been relaxed"

kirill.salykin15:02:32

• They cannot contain ‘.’ in the name part, or name classes. • Like symbols, they can contain a namespace, `:person/name`, which may contain ’.’s.

p-himik15:02:52

As per Rich's comment, the dots can be part of keyword names now.

rutledgepaulv16:02:12

anyone know if there’s a common name for this function?

rutledgepaulv16:02:17

(defn operate [& fs]
  (fn [tuple] (mapv (fn [[f x]] (f x)) (map vector fs tuple))))
=> #'example.core/operate
((operate identity inc) [1 2])
=> [1 3]
((operate identity inc dec) [1 2 0])
=> [1 3 -1]

rutledgepaulv16:02:45

it’s similar to juxt but for operating piecewise against a tuple

Alex Miller (Clojure team)16:02:44

not that I'm aware of but you can simplify that impl

rutledgepaulv16:02:59

simpler constructions welcome!

Alex Miller (Clojure team)16:02:32

why are you packing it into a vector, then pulling it back apart?

rutledgepaulv16:02:53

just to pair things up i guess

Alex Miller (Clojure team)16:02:02

(defn operate [& fs]
  (fn [tuple] (into [] (map #(%1 %2) fs tuple))))

Alex Miller (Clojure team)16:02:07

something like that is same?

dominicm16:02:32

I don't know, but I'd bet that the vector part should not be there. Collections are your general unit of abstraction. Type can be preserved at an outer level if you care.

rutledgepaulv16:02:02

yeah. idk for some reason i always assume vector for tuples, no ?

Alex Miller (Clojure team)16:02:16

I assumed v->v was important here for some reason

jsn16:02:29

(`mapv` then?...)

dominicm16:02:54

The input might be tuples, but output could be a collection of tuples?

dominicm16:02:42

Vectoritus is dangerous. Before you know it you have clojure/corev.clj with vector versions of every function in core :)

colinkahn16:02:27

If I have a namespace symbol is there a way I can find the file it’s defined in?

ghadi17:02:01

@colinkahn what's your underlying issue?

colinkahn17:02:11

I’m using https://github.com/weavejester/ns-tracker to watch source changes, the tracker only returns what namespaces have changed, but I need to do something with the actual files (move them somewhere etc).

colinkahn17:02:04

looking at tools.namespace it seems I could search files for matching namespace declarations, but hoping there’s a more straightfoward way

dominicm17:02:25

Tools namespace replaces - with _ and . with / to do that.

colinkahn17:02:16

Looking for full file paths though

dominicm17:02:48

You'll need to search the classpath and then convert the url back to a full path, or just assume src/.

lilactown17:02:46

honestly you could probably patch ns-tracker to return the file path, it’s already doing the reverse: file -> namespace

lilactown17:02:38

https://github.com/weavejester/ns-tracker/blob/master/src/ns_tracker/core.clj#L50 I bet right here you could add the file as metadata to the symbol and not have to change much at all. just spitballing, haven’t tried it!

colinkahn17:02:52

Thanks for the ideas @dominicm and @lilactown, I’ll see what I can come up with simple_smile

ghadi17:02:55

if you have an already loaded var, it also contains the file path @colinkahn

user=> (get (meta #'clojure.string/includes?) :file)
"clojure/string.clj"

ghadi17:02:18

(classpath-relative)

colinkahn17:02:08

In this case I just have the namespace symbol, but good to know

ghadi17:02:27

is the namespace loaded, or not yet?

colinkahn17:02:39

not yet, but I could load it

kwladyka17:02:07

Why use-fixtures have :each ond :once but can’t run fixture once per deftest? I miss that option. Only once per ns or for each test, while what I always need is once per deftest in ns.

kwladyka17:02:22

Do you have the same issue?

seancorfield17:02:53

:each runs around each "test", i.e., each deftest.

seancorfield17:02:28

So :each is "once per deftest".

seancorfield17:02:12

@kwladyka Can you explain what you're trying to do if that isn't what you need?

kwladyka18:02:34

hmm I want to have a few deftest in 1 ns and wrap this things with DB reset thing

seancorfield18:02:10

Sorry, I still don't understand.

kwladyka18:02:48

hmm maybe I confused myself yesterday… let me check this again

kwladyka18:02:14

because changin :once to :each demand to clean :once or restart REPL

kwladyka18:02:16

I could make a mistake

kwladyka18:02:54

oh ok my mistake, sorry

seancorfield18:02:15

You don't need to restart the REPL for that change to take effect. You may need to remove the namespace and reload just that one file tho', since you need to get rid of the old metadata on the namespace (you could just alter-meta on it if you knew the underlying implementation used 🙂 )

👍 4
hadils18:02:07

Anyone know a way to generate Clojure documentation from tools.deps? I see codox and codeina but they use leiningen. I tried a naive approach in my deps.edn but was unsuccessful in generating docs. Thanks in advance!

dchelimsky18:02:32

tools.deps is for dependencies, not build concerns like generating documentation. We use https://github.com/tomfaulhaber/autodoc generate the docs for aws-api: https://cognitect-labs.github.io/aws-api/

hadils18:02:24

Thanks @U0ENYLGTA! That is exactly the answer i need!

dchelimsky18:02:56

Glad to help.

Parenoid18:02:32

haha... Slack: "Upgrade to a paid plan to see 1 additional message from @<some user> that matches your search." omfg. long live IRC.

💩 4
andy.fingerhut21:02:12

http://clojurians.zulipchat.com has been logging many Clojurians Slack channels for at least a year now (maybe different start dates for different Slack channels, and some might not be at all). You can search there over that history.

Parenoid18:02:41

most of the communication by the users of an open source language in the hands of a private company, behind a paywall. smh.

thumbnail19:02:06

the archive of clojurians is searchable, see topic description

plins19:02:37

anyone familiar with https://github.com/ptaoussanis/tufte? Im trying to do a very basic example but Im getting a exception instead of 9 .. the problem is that the code im trying to profile is written using the -> operator

(defn add-2 [x]
  (Thread/sleep 2000)
  (+ 2 x))

(defn mult-by-3 [y]
  (Thread/sleep 1000)
  (* 3 y))

(profile
 {}
 (-> 1
     (p :x add-2)
     (p :y mult-by-3)))

noisesmith19:02:49

@plins the examples on the page have the keyword as the first arg to p

plins19:02:55

thanks for the clarifications! but unless im missing something, p is nested below profile at the docs

(profile ; Profile any `p` forms called during body execution
  {} ; Profiling options; we'll use the defaults for now
  (dotimes [_ 5]
    (p :get-x (get-x))
    (p :get-y (get-y))))

plins19:02:52

I thin Ill just use cljr to unwind all and do like its recommended

noisesmith19:02:21

oh I missed that, my bad

noisesmith19:02:58

the -> ensures that the keyword is the second arg to p

noisesmith19:02:24

you could use as-> to be more specific about the arg position, or just use let

noisesmith19:02:12

also, the examples don't use p inside profile

mloughlin22:02:34

I'm looking for Lisp implementations written in Clojure. I'd like to explore different methods of converting tokens into an AST. https://github.com/kanaka/mal/blob/master/impls/clojure/src/mal/reader.cljc uses an atom to track state, but I'd like to learn about alternatives. Anyone?

mloughlin22:02:41

An attempt at porting Norvig's Lis.py implementation (https://norvig.com/lispy.html) started me off down this rabbit hole :)

mloughlin10:02:07

I didn't think of using a non-persistent data structure 😁

andy.fingerhut22:02:16

There are the libraries tools.reader, tools.analyzer, and tools.analyzer.jvm, implemented in Clojure, and intended to be as compatible as they can be with Clojure's built-in alternatives. Not sure if that is in the ballpark of what you are looking for. https://github.com/clojure/tools.reader. https://github.com/clojure/tools.analyzer. https://github.com/clojure/tools.analyzer.jvm

👍 4
andy.fingerhut22:02:34

I believe they have a strong tendency to use immutable data structures whenever possible.