clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
Jim Newton 2021-04-30T08:15:03.295900Z

Does anyone recall if there’s been a discussion of added a goto primitive to Clojure? Apparently there is such an instruction in the JVM. Obviously you don’t need goto for high level user code. But sometimes it is good to have in macro expansions, if you want the macro to create extremely efficient code. Also when transcribing Knuth algorithms verbatim.

Jim Newton 2021-04-30T08:16:30.297Z

One example is when serializing a finite state machine into clojure code, it is extremely efficient to translate it into labels and goto, especially in light of the fact that tail call optimization is not an option.

Jim Newton 2021-04-30T08:20:34.299100Z

Another example is discrimination nets where the code represents a binary tree of if/then/else nodes. it might be the case that you want some of the nodes to be identical, copying the code causes an exponential explosion of code size, a goto would divide the code size by 2 every time it is used.

Jim Newton 2021-04-30T08:21:16.299500Z

again, that would be for machine (macro) generated code.

2021-04-30T08:22:33.300400Z

with jvm clojure you always have an option to write low-level java code (with GOTO instructions if you like) and use it in clojure code.

✔️ 1
Jim Newton 2021-04-30T08:23:06.300800Z

can I have a clojure macro expand to low level java code? or better, expand to JVM instructions?

2021-04-30T08:24:36.301900Z

you can (to some degree) use https://clojure.github.io/tools.emitter.jvm/ but I don’t think it will have any significant improvements forget that, it is for introspection, not for comsuming

✔️ 1
Jim Newton 2021-04-30T08:28:54.302700Z

Anyway, having some primitive operations directory in clojure would be useful. Humans aren’t the only ones who write code.

Jim Newton 2021-04-30T08:31:37.304600Z

I’ll create a thread in clojureverse.

2021-04-30T08:31:46.304900Z

right, not only, but I don’t think clojure team prioritize towards machines instead of humans.

2021-04-30T08:32:12.305400Z

better to start from http://ask.clojure.org

borkdude 2021-04-30T08:59:29.306500Z

@jimka.issy One relevant issue is some work done around recur-to which is a mechanism in loop which allows different recur targets

borkdude 2021-04-30T09:00:15.306800Z

https://www.youtube.com/watch?v=SJmK1R0ADnc

borkdude 2021-04-30T09:01:00.308Z

loop translates into fairly low level bytecode which could fulfil your needs

Jim Newton 2021-04-30T09:01:07.308200Z

very interesting. Thanks for the link. Would you mind also commenting on the askclojure thread?

borkdude 2021-04-30T09:01:14.308400Z

ok

Jim Newton 2021-04-30T09:02:28.309300Z

I’ll take a look at the presentation, but I can’t imagine how a DFA could be implemented with concentric loops. I’ll keep an open mind when I watch the video.

borkdude 2021-04-30T09:03:42.311Z

I don't know if you can, I don't know what a DFA is. Just for what it's worth.

1
Jim Newton 2021-04-30T09:04:20.311900Z

Can someone help me with human-speak terminology. I want to describe to an audience who is not clojure-savvy what kind of call-site argument lists are compatible with a function such as: (fn [a [b c] d e) ...) . How should I describe what type the 2nd argument is expected to be. Should I say tuple ?

borkdude 2021-04-30T09:04:47.312100Z

yes, tuple is common in Clojure

borkdude 2021-04-30T09:05:10.312600Z

although technically you can pass any vector in there

p-himik 2021-04-30T09:05:30.313100Z

Anything that supports nth.

Jim Newton 2021-04-30T09:05:42.313700Z

it can take a list, or cons, or vector, or lazy sequence, or or or or

borkdude 2021-04-30T09:05:50.313900Z

a tuple is constrained on size, while destructuring just accepts anything really, what p-himik says

borkdude 2021-04-30T09:05:59.314100Z

correct

Jim Newton 2021-04-30T09:06:19.314600Z

so is there a word which describes all objects supported by nth ?

Jim Newton 2021-04-30T09:06:54.315100Z

perhaps sequentials ?

borkdude 2021-04-30T09:06:55.315200Z

Returns the value at the index. get returns nil if index out of
  bounds, nth throws an exception unless not-found is supplied.  nth
  also works for strings, Java arrays, regex Matchers and Lists, and,
  in O(n) time, for sequences.

borkdude 2021-04-30T09:07:36.315700Z

perhaps seqable is better here since sequential? doesn't return true for strings

borkdude 2021-04-30T09:08:06.316100Z

but that also doesn't quite cover it since sets are seqable but not compatible with nth

borkdude 2021-04-30T09:08:18.316500Z

so yes, informally, sequential things

p-himik 2021-04-30T09:08:22.316700Z

Any ordered collection, I would say.

Jim Newton 2021-04-30T09:08:31.317Z

(defn seqable?
  "Return true if the seq function is supported for x"
  {:added "1.9"}
  [x] (clojure.lang.RT/canSeq x))

borkdude 2021-04-30T09:09:03.317600Z

I think what p-himik says is best: ordered things, like sequential collections, strings and arrays

borkdude 2021-04-30T09:09:17.317900Z

In Clojure it is most common to (sequentially) destructure on a vector or seq

borkdude 2021-04-30T09:09:57.318400Z

In wide-audience-speak you could even say "array-like things" or "list-like things"

1
Jim Newton 2021-04-30T09:10:42.319100Z

yes everyone will vaguely understand sequence-like or array-like

Jim Newton 2021-04-30T09:13:10.319900Z

Is that a typo in the docstring of nth ? or is that really intended “get returns nil if index out of bounds” ?

(defn nth
  "Returns the value at the index. get returns nil if index out of
  bounds, nth throws an exception unless not-found is supplied.  nth
  also works for strings, Java arrays, regex Matchers and Lists, and,
  in O(n) time, for sequences."
  {:inline (fn  [c i & nf] `(. clojure.lang.RT (nth ~c ~i ~@nf)))
   :inline-arities #{2 3}
   :added "1.0"}
  ([coll index] (. clojure.lang.RT (nth coll index)))
  ([coll index not-found] (. clojure.lang.RT (nth coll index not-found))))

borkdude 2021-04-30T09:15:41.320300Z

The function get returns nil, as opposed to nth

Jim Newton 2021-04-30T09:16:29.321300Z

ahh, the meaning is *Whereas get returns nil …, nth throws an exception.” is that the meaning?

borkdude 2021-04-30T09:17:13.322400Z

yes

1
2021-04-30T09:18:51.325Z

the only thing you can say for sure about that form (fn [a [b c] d e] ...) that this is a function of 4 arguments.

borkdude 2021-04-30T09:19:15.326600Z

and that it will crash on an argument which does not work with nth in the second position

Jim Newton 2021-04-30T09:19:22.327Z

@delaguardo, exactly the kind of subtleties in trying to describe what is happening. especially to a non-clojure-savvy programmer

2021-04-30T09:19:22.327100Z

other constrains probably should sit on top of the function via spec for instance

Jim Newton 2021-04-30T09:20:46.330800Z

in my opinion, since there are soooooo many useful type-like predicates in clojure core, int? number? sequential?, and since destructuring is so fundamental to how clojure works, there should be a predicate destructurable? which captures this nth-compatibility question.

2021-04-30T09:21:06.331500Z

“destructuring” is a process of extracting and binding information from structured data described by entity called desctructuring form which should follow some rules described in https://clojure.org/guides/destructuring

1
2021-04-30T09:21:27.332300Z

that’s my attempt to describe what is going on 🙂

2021-04-30T09:21:39.332600Z

Hello! I created some lib for using on developing my work projects, but I don't want to add it as a dependency in project.clj or deps.edn. Althow I want to be it allowed at every namespace in repl. I found a way:

lein repl
  (load-file "my_lib.clj")
once on repl start and then in any repl ns eval
(do
    (use '[my-lib :as ml])
    (ml/my-fn ....))
Is there any other convinient way of doing it? Or just altering standart classpaths? Maybe starting lein repl with some classpath parameters?

borkdude 2021-04-30T09:22:06.333200Z

@jimka.issy There is also a destructure function which is used when destructuring, maybe helpful in some way

2021-04-30T09:22:30.333300Z

you could sketch out it’s interface and propose in http://ask.clojure.org

borkdude 2021-04-30T09:23:25.334300Z

But since you are speaking to a wide audience, maybe it's better to not get into too much detail

✔️ 1
Jim Newton 2021-04-30T09:23:36.334600Z

@borkdude, I took a look at the code for destructure … it is shocking

bherrmann 2021-05-06T16:35:16.164100Z

You (concerned developer with commit rights) might want to add a comment to the destructure source to mention "destructure() is public in case other implementors need to leverage it, but not generally intended for public use. The the absence of docstring is to prevent it from showing up in the api docs" .... at or near https://github.com/clojure/clojure/blob/clojure-1.10.1/src/clj/clojure/core.clj#L4389

2021-04-30T09:24:09.334800Z

a bit aggressive ) maybe worth to add more details?

2021-04-30T09:24:28.335100Z

what particular you found shocking?

Jim Newton 2021-04-30T09:36:58.335300Z

sorry, don’t mean to be agressive. just when I look at the function, it appears to be an internal function having no docstring or comment explaining what it does. it’s not easy to understand what the function does.

Jim Newton 2021-04-30T09:37:20.335500Z

I suppose the function is not really intended for public consumption.

Jim Newton 2021-04-30T09:38:04.335700Z

nothing essentially wrong with hard to understand code, especially when not intended for general consumption.

Jim Newton 2021-04-30T09:39:04.335900Z

Sorry if my words come across like I’m an ass. I’m really a sweat guy. just sometimes not skilled in serializing my thoughts.

2021-04-30T09:45:18.336100Z

no hard feelings ) and yes, destructure function is for advanced usage which usually assume you are writing a complex macro

borkdude 2021-04-30T09:53:27.336300Z

destructure is used by clojure itself primarily

emilaasa 2021-04-30T10:13:49.336500Z

You could create a user.clj

2021-04-30T10:17:23.336700Z

Thanks, good way. But it's already created and added to git, and I dont want to alter it - if I'l require my lib there, then I'l have to send my lib to all my colegues, but they dont need it

emilaasa 2021-04-30T10:19:27.337Z

Maybe add in a developer source path in the project configthat's gitignored?

emilaasa 2021-04-30T10:19:46.337200Z

(defproject hello "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "<http://example.com/FIXME>"
  :license {:name "Eclipse Public License"
            :url "<http://www.eclipse.org/legal/epl-v10.html>"}
  :dependencies [[org.clojure/clojure "1.5.1"]]
  :source-paths ["dev"])

2021-04-30T10:21:07.337400Z

We have common project.clj and it's not git ignored. Can I create another one? I'm not sure what do you suggest, sorry

emilaasa 2021-04-30T10:21:32.337700Z

I mean you could git ignore the folder, call it local-dev or something

emilaasa 2021-04-30T10:22:00.338Z

But an even easier way is to just add it in your lein config probably, jsut as

emilaasa 2021-04-30T10:22:03.338200Z

just a sec..

2021-04-30T10:22:09.338400Z

yep, and all my local lib lives here.

emilaasa 2021-04-30T10:22:45.338600Z

Does it work to put it in your ~/.lein/profiles.clj ?

2021-04-30T10:23:59.339200Z

Hm, didn't try it, thanks. Maybe it will work, I'l try in a time.

emilaasa 2021-04-30T10:24:08.339400Z

"If you want to access dependencies or plugins during development time for any project place them in your :user profile. Your ~/.lein/profiles.clj file could look something like this:"

emilaasa 2021-04-30T10:25:24.340Z

I think that's what you want if you don't need to share this between devs.

2021-04-30T10:26:11.340200Z

Seems like that, yep. Thanks alot! Will try this way after work.

alexmiller 2021-04-30T13:20:46.340600Z

it's public in case other implementors need to leverage it, but not generally intended for public use

alexmiller 2021-04-30T13:21:18.340800Z

the absence of docstring is to prevent it from showing up in the api docs

borkdude 2021-04-30T13:21:28.341Z

It's pretty useful to have this, so thanks for including it anyway

1
alexmiller 2021-04-30T13:22:10.341200Z

having spent many hours in that function, I agree that it is far more painful to read/understand that it should be

alexmiller 2021-04-30T13:23:18.341400Z

and I apologize for the additional trauma I have inflicted upon the code and future readers :)

💥 1
😉 1
borkdude 2021-04-30T13:23:45.341600Z

I have ripped off this function in sci, and merged it with the CLJS version to make it a .cljc version

zackteo 2021-04-30T15:04:38.344400Z

just for mild curiosity's sake, when might one want to use destructure :thinking_face:

borkdude 2021-04-30T15:06:29.344600Z

Usually you don't need it, but it can be handy for debugging as well, to see how clojure destructures things

zackteo 2021-04-30T15:09:14.344800Z

I see I see!

alexmiller 2021-04-30T15:17:08.345Z

potentially if you were writing a macro or something you could explicitly call it, but really most macros just expand to a let or something else that will call it for you, so it is pretty rare to need to call it directly

zackteo 2021-04-30T15:48:24.351900Z

Hi Everyone :) I am trying to see how feasible it is to try creating a thin wrapper around optaplanner https://quarkus.io/version/1.7/guides/optaplanner . However, based on the example it seems like the set up for it can be very heavy on class creation - some of which have several annotations. Is there any similar project that I can take reference from? / Any advice for such interop? I understand that I might need gen-class and I do understand that so far, this undertaking seem a bit out of reach at my current proficiency levels ><

emccue 2021-05-03T19:47:30.488400Z

None - also sorry for the late reply

emccue 2021-05-03T19:47:41.488600Z

just whatever doodles you feel are appropriate

alexmiller 2021-04-30T15:52:35.352400Z

fyi, deftype supports annotations https://clojure.org/reference/datatypes#_java_annotation_support

zackteo 2021-04-30T16:01:08.352500Z

Right! Let me look into that first then :)

vncz 2021-04-30T16:19:05.352900Z

I like this rule a lot https://guide.clojure.style/#function-length even though I admit I sometimes fail to follow it

Jim Newton 2021-04-30T16:54:19.354200Z

Here is a link to the draft of a https://drive.google.com/file/d/1jcBy0Hu59wDVWHIyvl6g4CWPR-9GMbbc/view?usp=sharing which will accompany my upcoming ELS (european lisp symposium) talk. If anyone sees anything horribly wrong, there’s still time for me to fix it.

borkdude 2021-04-30T17:48:48.354300Z

First feedback: you call multi-arity functions "variable arity". I think this is confusing since we call (fn [&amp; xs]) a varargs function and "variable arity" might be confused with that. Instead, I would use "single arity" and "multiple arity" or "multi-arity"

borkdude 2021-04-30T17:52:43.354800Z

What is the trick you are using to go to the next page? Just layout the code so it works when you navigate page down, or is this an elisp package?

borkdude 2021-04-30T17:59:15.355100Z

The rest was pretty clear to me, kudos

Elliot Stern 2021-04-30T19:47:23.355400Z

Deterministic Finite Automata, usually

Elliot Stern 2021-04-30T19:48:00.355600Z

As opposed to nondeterministic ones, or NFA

Ed 2021-04-30T19:50:58.355800Z

@borkdude not sure what he's using to navigate pages, but Emacs does understand the form feed character ... So maybe that? http://ergoemacs.org/emacs/modernization_formfeed.html

raspasov 2021-04-30T21:13:05.356100Z

@jimka.issy pretty clear; One note: you have something called (satisfies …) . For a moment I got confused that this is (clojure.core/satisfies? …) https://clojuredocs.org/clojure.core/satisfies_q