Fork me on GitHub
#beginners
<
2020-04-01
>
negatifzeo00:04:10

Have a stupid question ๐Ÿ˜ž Why doesn't this function to generate a fibonacci sequence of length n work?

(defn createFib
  ([length] (createFib length [0 1]))
  ([length a] (if (= (count a) length) (a) (recur length (conj a (+ (nth a (- (count a) 1)) (nth a (- (count a) 2))))) )) )

noisesmith00:04:53

@negatifzeo (a) means "call the function a with no arguments"

negatifzeo00:04:31

Oh my gosh, so simple, And it works!

noisesmith00:04:00

user=> (let [a [1 2 3 4 5]]
               [(= (nth a (- (count a) 1))
                   (peek a))
                (= (nth a (- (count a) 2))
                   (peek (pop a)))])
[true true]
(fixed)

negatifzeo00:04:30

@noisesmith I like that!

negatifzeo00:04:32

Now I have another question... I get an integer overflow before long

negatifzeo00:04:42

How would I use longs or big ints?

noisesmith00:04:02

use +'instead of +

negatifzeo00:04:02

One more.... What does the N at the end of a very large number indicate?

noisesmith00:04:21

user=> (type 1N)
clojure.lang.BigInt

noisesmith00:04:31

it's a read/write notation for BigInt

negatifzeo00:04:47

Beautiful. Thank you!

noisesmith00:04:57

(you only see it with very large numbers usually, but even 1N is a bigint)

noisesmith00:04:26

related

user=> (type 1M)
java.math.BigDecimal

negatifzeo00:04:58

Not sure if I would have found this had I not asked here

noisesmith00:04:10

@negatifzeo if you can figure out the right regex, clojure.repl/find-doc can help a lot

user=> (find-doc #"\Wsum\W")
-------------------------
clojure.core/+
([] [x] [x y] [x y & more])
  Returns the sum of nums. (+) returns 0. Does not auto-promote
  longs, will throw on overflow. See also: +'
-------------------------
clojure.core/+'
([] [x] [x y] [x y & more])
  Returns the sum of nums. (+') returns 0. Supports arbitrary precision.
  See also: +
-------------------------
clojure.core/unchecked-add
([x y])
  Returns the sum of x and y, both long.
  Note - uses a primitive operator subject to overflow.
-------------------------
clojure.core/unchecked-add-int
([x y])
  Returns the sum of x and y, both int.
  Note - uses a primitive operator subject to overflow.
nil

noisesmith00:04:38

sadly the doc strings are not optimized for regex searchability, but the facility does exist

noisesmith00:04:50

bonus, it's not limited to core - it works with every defined function with a doc string

negatifzeo00:04:14

Also, can I ask what you use to format your code so that it's so readable?

noisesmith00:04:45

here in slack I use the standard markup three ` introduces a code block, there's also a button for it

negatifzeo00:04:55

The final form:

(defn createFib
  "Usage: (createFib n), creates a fibonacci sequence of length n"
  ([length] (createFib length [0 1]))
  ([length a] (if (= (count a) length) a (recur length (conj a (+' (peek a) (peek (pop a)) ))) )) )

seancorfield00:04:43

Just a note on Clojure style, we use kebab-case rather than camelCase for names.

aaron-santos04:04:37

Any suggestions for porting https://github.com/pomber/didact/blob/master/didact.js to Clojure? The mutable tree structure of fibers is throwing me for a loop. Zippers came to mind, but there are several references to locations within the tree at the same time which complicates the matter considerably.

michael74004:04:38

does clojure have an all function? (apply and [true true false]) doesn't work i guess because and is a macro

michael74004:04:12

never mind me

jimka.issy07:04:29

HI Everyone. I have a problem with is in clojure.test . Is there an is-not I can use? If I simply test (is (not ...)) then the failure messages are uninformative. If (is (> a b)) fails, I get a message like (not (> 1 2) but when (is (not (> a b))) fails I just get a message (not (not true)) . Certainly for > I could choose a better predicate for the test, but in general (is (f a ...)) vs (is (not (f a ...))) is problematic.

(deftest t-nullable
  (let [a 1 b 2]
    (is (> a b))
    (is (not (> b a)))))

(run-tests 'clojure-rte.core-test)
FAIL in (t-nullable) (form-init4386036104585295471.clj:33)
expected: (> a b)
  actual: (not (> 1 2))

FAIL in (t-nullable) (form-init4386036104585295471.clj:34)
expected: (not (> b a))
  actual: (not (not true))

jimka.issy07:04:06

Is there a cousin of isa? which tests not type inclusion, but rather type intersection? I.e. given two isa? compatible type designators how can I know whether there can exist an object which is a member of both types?

didibus08:04:49

Not directly,but you can call ancestors on both, and then do a set intersection on the sets they return: https://clojuredocs.org/clojure.core/ancestors

jimka.issy08:04:33

@didibus, does it suffice to call ancestors once for A and once for B and find the intersection of those two results, or do I need to walk up the return value and keep calling ancestors ?

jimka.issy08:04:00

E.g., does this suffice? Note, that I'm calling not-any? twice rather than calling intersection, because I don't need the intersection, I just need to know whether the intersection is empty.

(defn disjoint? [t1 t2]
  (let [ancestors-1 (ancestors t1)
        ancestors-2 (ancestors t2)]
    (and (not-any? (fn [a2] (contains? ancestors-1 a2)) ancestors-2)
         (not-any? (fn [a1] (contains? ancestors-2 a1)) ancestors-1))))

jimka.issy09:04:15

This implementation is sadly wrong. ๐Ÿ˜ญ It asks whether the two types have a common supertype, not whether they have a common subtype.

jimka.issy09:04:09

I believe it should be the following:

(defn disjoint? [t1 t2]
  (let [descendants-1 (descendants t1)
        descendants-2 (descendants t2)]
    (and (not-any? (fn [a2] (contains? descendants-1 a2)) descendants-2)
         (not-any? (fn [a1] (contains? descendants-2 a1)) descendants-1))))

jimka.issy14:04:26

Found another bug in this function disjoint? Here is my current implementation

(defn disjoint? [t1 t2]
  (and (not (isa? t1 t2))
       (not (isa? t2 t1))
       (let [descendants-1 (descendants t1)
             descendants-2 (descendants t2)]
         (and (not-any? (fn [a2] (contains? descendants-1 a2)) descendants-2)
              (not-any? (fn [a1] (contains? descendants-2 a1)) descendants-1))))) 

jimka.issy14:04:54

The previous version was answering false in the case one type isa? subtype of the other

didibus09:04:05

Hum, I believe ancestors will return the following chain of parents, so you shouldn't have too walk up it

didibus09:04:31

I think that's the difference with the parents function, which will only return the immediate parents, ancestors I think will walk up the parents and aggregate their parents and their parents parents all the way for you

jimka.issy09:04:24

Looking at the documentation forย https://clojuredocs.org/clojure.core/typeย I see how to find a type of an object. And in the see-also section it talks about the functionย `instance?`ย which tests whether an object is a member of a designated class.ย  Is the documentation using the word class and type interchangeably here? What is the correct way to check type membership, assuming I have a type designator compatible withย `isa?`ย ?

penryu09:04:07

According to the doc:

user=> (doc type)
-------------------------
clojure.core/type
([x])
  Returns the :type metadata of x, or its Class if none
From what I've seen, it looks like type/`isa?` and class/`instance?` are counterparts with each other.

penryu09:04:43

class and instance? dealing strictly with java object hierarchy; type/`isa?` deal with derived types, falling back to Java classes if no derived type hierarchy is available.

jimka.issy09:04:01

No, as far as I understand isa? takes two type designators and tells whether one is a subtype of the other. I'm looking for a function which takes an object and a type designator and asks whether the object is a member of that type.

jimka.issy09:04:39

i.e., something that can be called like instance? but which accepts any 1st argument which is compatible with isa?

timur05809:04:10

@jimka.issy (isa? (type x) y)?

penryu09:04:51

Yes, (isa? (type a-value) a-type) vs (instance? a-class an-object)

penryu09:04:04

But because isa? and type fall back to Java type hierarchy, they will likely fit.

penryu09:04:18

and since you mention you have an isa? compatible type designator, type would make more sense to me.

jimka.issy10:04:13

Good suggestions.

jimka.issy10:04:14

Thanks. But since I really don't understand all the flexibility of isa?, what's the best way to test my code? How can I generate a huge set of isa? compatible arguments and corresponding instances? Perhaps I could look at the testing code for isa? itself? Does anyone know how to locate that?

penryu10:04:23

Are you using derived types? Or is that what you're looking at doing?

jimka.issy12:04:04

Hi penryu, for the moment here is what I think I'm doing. I'm implementing a DSL which lets the user talk about types. I want to claim on my DSL that I accept any type which isa? supports.

penryu19:04:28

iiuc, as long as your program uses type, isa?, or by extension defmulti/`defmethod`, this is implicitly true.

penryu19:04:04

but I haven't done a lot with derived types

jimka.issy10:04:04

I'd like to write a function which takes a single argument and distinguishes several cases: (1) anything other than list, (2) empty list (3) singleton list (4) non-singleton list. Can someone suggest the most idiomatic way of doing this?

(cond (not-a-list x) ...
      (empty-list x) ...
      (singleton-list x) ...
      (non-trivial-list x) ...)
Here is what I'm trying.
(cond (not (list? pattern)) ...
         (= pattern ()) ...
         (not (rest pattern)) ...
         :else ...)

penryu10:04:02

Based on what I know of your question, I might start with something like:

(def do-stuff [x]
  (if (sequential? x)
    (case (count x)
      0 (do-empty x)
      1 (do-single x)
      (do-longer x))
    (do-not-list x)))

penryu10:04:40

This handles sequences other than actual lists (eg, vectors) as well. If you're expecting the method to be called with different types, you might consider multimethods.

aviv11:04:45

Using clojure.jdbc I would like to write a method that does update-or-insert-rows [db table rows where] where rows could be a seq of maps. this would work for 1x row: (defn update-or-insert [db table row where] (sql/with-db-transaction [t-conn db] (let [result (sql/update! t-conn table row where)] (if (zero? (first result)) (sql/insert! t-conn table row) result)))) Is there any way using insert-multi! or doing a batch operation and not calling this method for each row? assuming my DB would need to update some data. or a way to use ON DUPLICATE KEY UPDATE..., I can also delete > insert - which I prefer not to

mitchell_clojure13:04:15

you might want to just call sql/execute! with a statement that has the on duplicate key update... clause

aviv14:04:16

yea but i'm looking for some abstraction, as I would need to parse all given maps... etc to query,

seancorfield16:04:49

@aviv The problem (from a library point of view) is that upserts have different syntax across different databases, and there are also different ways to implement upsert even for a single DB, depending on exactly what semantics you want and what trade offs you want to make.

aviv19:04:53

How would you tackle this kind of scenario? ๐Ÿ™‚ @

seancorfield20:04:46

@aviv When I researched this for MySQL (which is what I use at work), I found three completely different approaches with three different sets of trade offs, so the approach I would code up would very much depend on the specific trade offs I was willing to accept in those specific circumstances.

seancorfield20:04:41

We write upserts quite often at work, but never for bulk updates/inserts -- they are always single row solutions -- and we do it in different ways depending on all sorts of parameters to the problem (how write heavy the table is, whether a double insert actually matters (and whether it is detectable through key constraints -- it isn't always). So the logic varies a lot.

seancorfield20:04:32

If I was using PostgreSQL, I would no doubt have the option of different solutions, with different trade offs, due to the different syntax/semantics that PG provides compared to MySQL.

aviv20:04:56

I see, by double insert you mean duplication. we use MySQL and currently I choose to batch delete & insert compared to upsert-each-row of the batch

aviv20:04:23

I could test it timing as this is my only concern atm

seancorfield20:04:49

When deleting and inserting, there's also the consideration of what happens if another process queries for the record concurrently and doesn't find it.

seancorfield20:04:48

For some tables, it's safer for us to do an insert, then delete the older record. For other tables, we do an update and if that hits no records we do an insert -- but then you have to deal with potential concurrent insertions (two threads both do the update and both get zero rows so both of them then try to insert a new record... which you may have to then detect and fix if there's no constraint violation on the inserts). So many fun possibilities ๐Ÿ™‚

aviv07:04:07

Deleting and inserting is also much-less-efficient than an update query

aviv07:04:23

as a rule of thumb it's better to do an upsert rather than delete-insert I guess

aviv07:04:42

(we have totally different timezones so responding in delay ๐Ÿ™‚)

seancorfield14:04:25

Correctness outweighs efficiency. Again, the choice of approach depends on the exact problem and the trade offs that are appropriate.

jimka.issy16:04:06

Can someone help me understand why this evaluates to false.

(let [a 100] (list? `(:or ~a)))
while this evaluates to true
(list? '(:or 100)) 
and this evaluates to true as well.
(= '(:or 100) (let [a 100] `(:or ~a)))

seancorfield16:04:41

= is value-based in Clojure so, for example (= [:a 100] (list :a 100)) produces true even tho' we're comparing a vector and a list.

seancorfield16:04:20

list? itself tests whether its argument is an instance of a specific type: IPersistentList

user=> (source list?)
(defn list?
  "Returns true if x implements IPersistentList"
  {:added "1.0"
   :static true}
  [x] (instance? clojure.lang.IPersistentList x))

jimka.issy16:04:39

so backquote returns a vector?

seancorfield16:04:59

user=> (type `(:or 100))
clojure.lang.Cons

seancorfield16:04:20

user=> (type '(:or 100))
clojure.lang.PersistentList

jimka.issy16:04:01

it prints with parenthesis not with brackets.

jimka.issy16:04:07

why is a Cons not a list? Should I be as confused as I am?

seancorfield16:04:26

user=> (ancestors clojure.lang.Cons)
#{clojure.lang.ISeq clojure.lang.Sequential .Serializable clojure.lang.IPersistentCollection clojure.lang.ASeq java.lang.Iterable clojure.lang.IObj clojure.lang.Seqable java.util.Collection java.lang.Object clojure.lang.Obj clojure.lang.IHashEq java.util.List clojure.lang.IMeta}
Cons is a lot of things -- including an IPersistentCollection but not an IPersistentList

seancorfield16:04:33

Backquote is a special construct, most often used with macros.

user=> (macroexpand '`(:or 100))
(clojure.core/seq (clojure.core/concat (clojure.core/list :or) (clojure.core/list 100)))
user=> (macroexpand '(:or 100))
(:or 100)

seancorfield16:04:07

This might help explain some of the "punctuation" you'll see in Clojure https://clojure.org/guides/weird_characters

jimka.issy16:04:16

which part of the punctuation link are you referring to? And why do we have to different list-like structures which print the same and both look like lists but are not both lists?

clojure-rte.core> (let [a 100] `(:or ~a))
(:or 100)
clojure-rte.core> '(:or 100)
(:or 100)
clojure-rte.core> 
They print exactly the same.

seancorfield16:04:40

That page describes what single quote and backquote (syntax quote) do.

seancorfield16:04:13

Printing data structures is "lossy" -- partly because data structures have to be realized in order to display them as characters. So a lazy seq and a cons will both get realized and printed as "lists".

jimka.issy16:04:06

Yes thanks for the link. The backquote is familiar to me. and the page says that parentheses denote "List"s.

jimka.issy16:04:05

Even more bizarre:

jimka.issy16:04:13

clojure-rte.core> (type `(:or))
clojure.lang.PersistentList
clojure-rte.core> (type (let [a 100] `(:or ~a)))
clojure.lang.Cons
clojure-rte.core> 

alexmiller16:04:30

type is showing you a concrete type, but the abstractions that type implements are the more important part (which you're not seeing)

jimka.issy16:04:32

clojure-rte.core> (rte-list? (let [a 100] `(:or ~a)))
false
clojure-rte.core> (= 'clojure.lang.Cons (type (let [a 100] `(:or ~a))))
false
clojure-rte.core> (type (let [a 100] `(:or ~a)))
clojure.lang.Cons
clojure-rte.core> 
can I test for list or Cons?

alexmiller16:04:34

lists are IPersistentList, and more generally seqs (ISeq) are logical lists, so even more abstract. all lists are seqs, not all seqs are lists

jimka.issy16:04:02

why does this return false?

(= 'clojure.lang.Cons (type (let [a 100] `(:or ~a))))

dpsutton16:04:57

the type isn't a symbol. remove the '

alexmiller16:04:37

because 'clojure.lang.Cons is a symbol but type returns a Class instance

alexmiller16:04:16

user=> (= clojure.lang.Cons (type (let [a 100] `(:or ~a))))
true

alexmiller16:04:47

but as a caution, it's never a safe thing to compare class instances for equality - the jvm uses a hierarchy of classloaders and class instances are unique per classloader

alexmiller16:04:09

and classes loaded in different classloaders are not =

jimka.issy16:04:12

I need a scotch. now ๐Ÿ™‚ Thanks for helping me understand. It is really surprising to a lisper that `(something something) does not return a list :-[

alexmiller16:04:21

it does return a list

jimka.issy16:04:46

it doesn't return a list according to the list? function

alexmiller16:04:30

I think for the question you're asking, seq? is actually more appropriate

alexmiller16:04:33

user=> (seq? (let [a 100] `(:or ~a)))
true

dpsutton16:04:35

it does return something that answers to car and cdr though. its a seq which has first and next

alexmiller16:04:16

seqs are logical lists (a list abstraction). lists in Clojure are specifically persistent list collections, which is a narrower scope

jimka.issy16:04:41

but [1 2 3] also has a first and rest

alexmiller16:04:50

it doesn't actually

alexmiller16:04:05

first and rest take a seqable and coerce them to a seq

jimka.issy16:04:09

clojure-rte.core> (first [1 2])
1
clojure-rte.core> (rest [1 2])
(2)
clojure-rte.core> 

alexmiller16:04:21

vectors are seqable and coerced to a vector seq before the operation is applied

alexmiller16:04:41

so vectors don't "have" a first and rest, they can produce a seq view which does

alexmiller16:04:51

(as do maps, sets, etc)

alexmiller16:04:09

concrete lists directly satisfy the logical list abstraction

jimka.issy16:04:15

So is the list? function simply poorly documented?

jimka.issy16:04:27

or poorly named?

alexmiller16:04:34

no, it's very accurately documented

alexmiller16:04:59

the gap here is in your prior knowledge of lists where list means something different

alexmiller16:04:28

(I'm not saying you're wrong to be clear, I'm saying Clojure defines things in a subtly different way)

jimka.issy16:04:17

Alex, you said a minute ago that (something something) returns a list, but it is list for which list? returns false. So it appears that either the function has a bug, or is misnamed.

jimka.issy16:04:01

its ok for there to be bugs. the world is full of bugs. We just need to understand them and move on with creating beautiful programs.

ordoflammae16:04:13

@jimka.issy, there's a difference between a clojure PersistentList and a sequence, which is commonly also called a list.

ordoflammae16:04:53

Most of the time, when you're thinking of a "list", what you really want is a sequence.

ordoflammae17:04:07

A clojure list is a specific type of sequence.

noisesmith17:04:34

yeah, seq? is a much more interesting predicate than list? is

alexmiller17:04:37

there are two levels of "list" here, and Clojurists often talk about them ambiguously

jimka.issy17:04:51

@ordoflammae I think the list? is misnamed. it does not check for whether somethign is a list, rather it checks for whether something is a clojure.lang.IPersistentList

alexmiller17:04:58

seqs are logical list abstractions, lists are persistent list collections

ordoflammae17:04:04

@jimka.issy,that's exactly what it's supposed to do.

alexmiller17:04:12

both are often referred to generically as "list"

alexmiller17:04:21

and both print the same

ordoflammae17:04:39

In technical terms, what you are thinking of is a sequence, but we just call it a list in every-day speech.

noisesmith17:04:03

regardless of the ontological questions of what is or isn't a "list", pragmatically speaking the predicate people usually need is seq?

alexmiller17:04:07

the list? predicate is specifically asking about the narrower persistent list collection, not the broader seq logical list

jimka.issy17:04:38

Am I the first person to be confused about this?\

alexmiller17:04:51

I doubt it :)

noisesmith17:04:11

it's a recurring topic from the #clojure IRC :D

ordoflammae17:04:30

XD, I was confused about it when I started learning clojure; no sweat.

alexmiller17:04:33

if you haven't seen https://clojure.org/reference/lisps, it sounds like it might help

jimka.issy17:04:50

So I'm defining a DSL where the user will type in a ???list??? like the following (:* a b (:cat (:+ d e) (:+ (:or a b)))) So does my parser for this need to check for list or sequence to distinguish leaf nodes from tree nodes?

alexmiller17:04:43

I would use seq? (or even more generically sequential? or coll? depending on whether vectors or sets etc are allowed)

jimka.issy17:04:11

the order is critically important so I'd say that I don't allow sets

noisesmith17:04:14

coll? would work with that input - but use sequential if you don't allow sets

alexmiller17:04:37

if scope is what you have there, I'd use seq?

jimka.issy17:04:41

are sets coll?

jimka.issy17:04:25

my liberally regulary uses `(this and ~that) during the descent

jimka.issy17:04:10

is a set a seq?

alexmiller17:04:01

as I said above, vectors, maps, and sets are not seqs, but they are seqable (can produce a seq view by calling seq on them)

jimka.issy17:04:50

no, doesn't seem to be

dpsutton17:04:10

(seq #{:a}) is (:a) but (seq? #{:a}) is false

jimka.issy17:04:38

Looking at my code, the thing that I'm assuming about the data structure is that I can destructure it with [first & rest] and I can build it with back-quote, paren, and @

lockdown-17:04:50

I think he has a point about lists (identical? some-list (seq some-list)) ๐Ÿ˜‰

didibus17:04:02

Hum, to distinguish leaf from tree, you can also check for emtpyness or nil depending on your use of rest or next

noisesmith17:04:32

calling rest on :or would blow up though

noisesmith17:04:38

and :or is a leaf

didibus17:04:56

Ah ya, nevermind, I see your need for seq? now

jimka.issy17:04:06

(:or x y z) is not a leaf because it is a ???list??? whose first element is in the syntax of my dsl. However (or x y z) would be a leaf because it doesn't match anything my parser is looking for. I would thus assume that (or x y z) would be something the user thinks is compatible with isa? , and if not, it's not my fault, it's a user error.

noisesmith17:04:58

@jimka.issy oh I must have misunderstood - usually when walking nested lists the collections are branches and non-collections are leaves

noisesmith17:04:49

if (:or x y z) isn't a leaf though, that means :or itself is right?

jimka.issy17:04:10

:or a syntax element in the DSL. it indicates which functions handle the x, y, and z depending on the operation we are performing. So the question of whether :or is a leaf never comes up.

didibus17:04:11

From memory, list? is the predicate for things constructed with the constructor list

jimka.issy17:04:46

if that's true, then it really does make sense.

didibus17:04:39

But, because you also have Vectors, and Java ArrayList and LinkedList and all these other kind of conceptual list like things, though not the things created by the list function

didibus17:04:58

Clojure Also has the concept of a sequence

didibus17:04:11

And a sequential

didibus17:04:47

Oh and seqable, and yes, at that points it gets tricky

jimka.issy17:04:03

I'm not sure whether it is a good idea or bad to allow the user to use other sequences for the dsl. for example should I treat (:or x (:and y z)) the same as [:or x [:and y z]] or even allow to mix and match? And if I want to disallow it, how would I?

didibus17:04:07

list? should check only for the first

didibus17:04:17

vector? only the second

didibus17:04:30

coll? for both

jimka.issy17:04:38

list? does not check the first because it fails on something generated by backquote/tilde.

didibus17:04:23

Hum.. are you sure?

jimka.issy17:04:40

yes, that was the beginning of the conversation.

didibus17:04:42

You don't do any intermediate processing on it?

jimka.issy17:04:04

(let [a 100] `(:or ~a))

jimka.issy17:04:10

list? returns false on that

didibus17:04:29

So ya, this gets tricky. The quote will return a list?

didibus17:04:47

But it seems the backquote doesn't create a list? but a seq? I think

jimka.issy17:04:54

normal quote returns a list? and backquote sometimes returns a list? but not always

didibus17:04:49

It's possible, I would say that's an artifact of the reader implementation

didibus17:04:01

And backquote

jimka.issy17:04:42

Thanks everyone for the help. I'm quitting for the day. will start again tomorrow morning

jimka.issy17:04:46

in confinement in France

didibus17:04:01

I don't think you can easily distinguish the two. Because seq? allows more than just what backquote might return. I don't know there is a supertype of just what backquote returns + list?

didibus17:04:30

Good luck, I'm also really curious to see the result of what you're cooking up

alexmiller17:04:42

I think it's a mistake to think of ' or ` as "returning" anything - these are syntax interpreted by the reader

alexmiller17:04:50

you can use both of them on any data type. what that means, depends.

alexmiller17:04:31

the fact that you're using quoting here should be irrelevant - define the syntax you want in terms of Clojure data

didibus17:04:12

Hum, ya I guess that can make sense. Not to say that if backquote say on () returned a list?, his problem would be solved. but obviously, it does not. So he might be better of coercing things himself.

didibus17:04:22

To the exact type he needs

noisesmith18:04:00

don't coerce, just use the right predicate for what you are checking for

didibus18:04:13

Though I expect ' to return me the literal that follows

didibus18:04:24

But backquote is a weird one

noisesmith18:04:12

using list? also means that you break everything if you preprocess your data with standard collection functions like map

didibus18:04:18

Say you wanted to allow only things returned from backquote over a () and lists? , but not vector? ArrayList, etc.

didibus18:04:50

doesnt that include vector?

noisesmith18:04:14

vectors aren't seqs

didibus19:04:52

Ah ya ok, I think I often get seq? and seqable? and sequential? mixed up as to what is which

didibus19:04:24

So seq? is all the XXXSeq classes + IPersistentList ?

noisesmith18:04:17

user=> (seq? [])
false

noisesmith18:04:34

what people think are "lists" generically are seqs

contato50918:04:43

Hi, I'm have some problems when do a minus operation with doubles values like: (- 10.52 10.42) I'm get a number 0.09999999999999964 . Someone can explain why, and how to fix it?

noisesmith18:04:13

that's just doubles being doubles isn't it?

noisesmith18:04:25

you can ask for rounding with a specific precision iirc

lockdown-18:04:28

Read about floating point arithmetic

contato50918:04:06

I see now, i was thinking this was a clojure error, but I test in others languages and I'm getting the same result

andy.fingerhut18:04:10

Here is a link to part of Clojure equality guide, that has a link to a widely referenced article on floating point representations and why they are approximations: https://clojure.org/guides/equality#_floating_point_numbers_are_usually_approximations

bfabry18:04:24

the answer btw is if possible use ratios, if not use BigDecimal user=> (- 1/3 2/3) -1/3 https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html

luis.geniole18:04:54

๐Ÿ™‹ Roll call! Who else is here?

seancorfield18:04:27

@luis.geniole There are 9,602 members in this channel ๐Ÿ™‚

luis.geniole18:04:42

Quite a few eh

seancorfield18:04:26

Feel free to ask Clojure-related (beginner) questions here but it's not a water-cooler for general chat.

lockdown-18:04:46

can you see how many are online? can't find where

seancorfield18:04:34

You can't get accurate numbers of the online members of a channel, just total.

seancorfield18:04:05

Much depends on whether folks have Slack set to show them "away" after some idle time, as well.

seancorfield18:04:29

Feel free to ask questions about Slack itself in #slack-help

lockdown-18:04:49

darn slack! ๐Ÿ˜‰

nbtheduke19:04:46

is it possible to have a multimethod for multiple dispatch values?

nbtheduke19:04:39

like (defmethod X [:foo :bar] ...) that catches both :foo and :bar values?

alexmiller19:04:12

you can have multiple methods that invoke the same function

alexmiller19:04:36

and there are some helper macros in various utility libs that get rid of the boilerplate for that

alexmiller19:04:52

as you can see, there's not much to it

nbtheduke21:04:16

cool, thank you