Fork me on GitHub
#clojure
<
2021-08-28
>
dpsutton00:08:13

i remember being astonished that he stated casually " i had to create a new backend for clojure.match to match macro expansion back into the original macros". that's the gist but i might be misremembering some bits of it. really incredible

bronsa00:08:24

well, it was abusing core.match so mutch that the generated code hit some hotspot bugs, so I had to change how core.match compiled expressions to get around that :)

dpsutton00:08:44

i'll have to rewatch to remind myself šŸ™‚

bronsa00:08:23

I remember not touching that code in a couple of months and then trying my demos on the last hour of the flight to baltimore, and nothing worked

dpsutton00:08:35

and back to ocaml he went šŸ™‚

bronsa00:08:10

I've brought a lot of lisp-y idioms into it at least :)

escherize00:08:28

Whatā€™s a good way to deterministically and sort-of-sanely indent clojure code?

escherize00:08:55

I am looking to make:

(defn reverse-a-string [s] (apply str (reverse s)))
and
(defn
  reverse-a-string
  [s]
  (apply
   str
   (reverse
    s))
  )
map to the same semi-readable thing, or collide, as it were.

bronsa00:08:13

look at cljfmt

escherize00:08:43

Yeah, I think cljfmt would work iff I remove newlines myself first. but if not, then anything with [[:block 0]] will not map the same way, since:

(foo bar                           (foo bar
baz            == formats to =>         baz
bang)                                   bang)
but
(foo bar baz bang)   == formats to =>   (foo bar baz bang)

hiredman00:08:51

I usually use the code format feature of clojure.pprint, it isn't entirely to my taste but 80/20

didibus00:08:46

Zprint can probably do whatever you want: https://github.com/kkinnear/zprint

didibus00:08:44

Its supposed to be a code re-writer, so it doesn't just re-format, it rewrites the code using the defined rules.

hiredman00:08:29

Anything you want except avoiding adding a new dependency šŸ™ƒ

didibus00:08:46

Hum, well it seems they want a formatter, which you'd normally use as a tool in your build I'd assume. Not a pretty-printer (though it can do that too)

escherize00:08:36

Yeah I actually want to make sure identical programs collide even if theyā€™re whitespaces are indented differently, but I want to keep a (sorta) readable copy of the programs around too

escherize00:08:07

otherwise Iā€™d just do (pr-str (read-string source-string))

hiredman00:08:44

Then define a hash based on the data structure after reading, not based on the serialized format

escherize00:08:17

and just save the source string as-is, that makes sense šŸ™ˆ

didibus00:08:46

classic zprint -- ignores whitespace in function definitions and formats code with a variety of heuristics to look as good as hand-formatted code

dpsutton00:08:27

Does lsp have the command line arg api yet? That could maybe solve this with no dependency inside the project

hiredman00:08:52

You'll still run into equivalence issues with variable names, etc, and clojure isn't strongly normalize

didibus00:08:30

I guess it depends if you're trying to do some real kind of program equivalence? Or just want like your Code Diffs to reflect only code change and not any formatting. For the latter zprint is really good, for the former, I mean.... good luck šŸ˜›

darshanime00:08:28

is it possible to use clojure.test/is inside with-redefs? when running lein test, I am getting FAIL for assertion but the tests are not failingā€¦

hiredman01:08:56

Async nonsense

hiredman01:08:14

You are running the test assertion on another thread

darshanime01:08:26

oh didnā€™t know that. how can i fix this?

hiredman01:08:07

That is just my first immediate guess as to why your assertions are failing, but the test is not

hiredman01:08:33

It should be fairly obvious where are starting a new thread of execution

darshanime01:08:18

oh i thought clj is running the multiple threads for with-redefs here and was really surprised for a second. nah, iā€™m just doing normal func callsā€¦

hiredman01:08:49

With redefs doesn't touch clojure test, so an interaction there is unlikely

hiredman01:08:02

Are you using fixtures?

hiredman01:08:45

An exception bubbling out of a fixture with being caught can cause weird issues

darshanime01:08:52

yes, but the fixtures is only to mount/start things, no exceptions being thrown thereā€¦

darshanime01:08:36

i am with-redefs http/get, which might be running in a separate thread internally, let me try to poke around with itā€¦

hiredman01:08:13

Double check, I assume the fixture is also stopping things, that is where I would expect the exception of that is what it is

darshanime03:08:20

you were right, it was the thread situation. i forgot we are using hystrix, which is a thread jungle! cmiiw, the lesson is that the assert failures should happen on the same thread which runs the test?

hiredman03:08:39

Yeah, you can technically get things to work correctly if you use something like bound-fn (because clojure.test depends on bindings) but it is better to keep all your assertions on the main thread.

p-himik12:08:13

The docstring of = says: "compares numbers and collections in a type-independent manner." And yet:

user=> (= 1. 1)
false
Does it mean the docstring is incorrect? Or how else one could interpret that part of the docstring?

potetm13:08:22

It appears to be talking about int/long and float/double conversions.

potetm13:08:13

=> (identical? (long 1)
               (int 1))
false
=> (= (long 1)
      (int 1))
true

Noah Bogart13:08:26

It does content checking, not type coercion

potetm13:08:57

static public boolean equal(Number x, Number y){
	return category(x) == category(y)
			&& ops(x).combine(ops(y)).equiv(x, y);
}

potetm13:08:28

so it checks the ā€œcategoryā€ (int/float/ratio/decimal) and then checks the value

p-himik13:08:54

Thanks! Sounds like the docstring could be made less ambiguous with that information. I see now that there's https://clojure.org/guides/equality#_summary but it's a resource that's external to the source.

vemv14:08:23

I would say that one cannot put a primitive long into a vector, is that correct? i.e. (vector (long 1)) produces a vector of one non-primitive Long

Alex Miller (Clojure team)14:08:41

correct, Clojure collections always hold objects (other than the primitive vectors created via vector-of)

vemv14:08:15

thanks! && TIL about vector-of

Alex Miller (Clojure team)14:08:10

the caveat with the primitive vectors is that their APIs still require boxing to objects so you don't get any benefit in computations on them, but you do get memory savings

Alex Miller (Clojure team)14:08:55

with primitive arrays you (potentially) get both, but they're mutable so much greater care is required

djblue22:08:15

What's the expected result for (:k (sorted-map 'k 0)) ?

R.A. Porter16:08:38

Ugh. Not a fan of that behavior at all. Even being explicit, and calling (get (sorted-map 'k 0) :k) will result in the exception, because even that calls compare. I consider that an implementation bug.

R.A. Porter16:08:08

Same behavior as in Java when working with a SortedMap impl (such as TreeMap), but expected as it's a strongly typed language. If you have control over the map, I think I'd write my own implementation that actually enforced some light typing requirements. Internally, your put and get implementations could check the provided keys to see if they are type-comparable to the defined keys of the map and if not, short-circuit and return a nil for get and, well probably still exception on a put/putAll.

andy.fingerhut02:08:37

sorted maps require that keys are comparable to each other, via a comparator method that takes 2 key values (or a key value already in the map, and one you are trying to look up or add). If you can come up with a custom comparator function that suits your purposes that takes 2 arbitrary values and returns a reasonable one of 3 values (less than, equal to, greater than), you are welcome to write that comparator function yourself.

andy.fingerhut02:08:58

It isn't exactly a trivial thing to do for arbitrary pairs of values of arbitrary types, though.

R.A. Porter14:08:30

Not surprising to someone with Java experience, but the docs for sorted-map make no indication of that and there's a non-trivial percentage of Clojure developers with no Java experience and limited knowledge of the underlying implementation details. We probably shouldn't ask them to do a deep dive into the implementation details for something that could be better documented.

andy.fingerhut11:08:09

The doc strings built into Clojure are considered by many to be more concise or terse than they would prefer. That is a design choice by the Clojure core developers that seems unlikely to ever change. On the other hand, anyone with a free public account can add examples, and comments with explanation, to http://ClojureDocs.org, explaining any facets or details about sorted-map, or any other Clojure function, that they wish.

andy.fingerhut11:08:48

I also don't think that there is a "universal comparison function between two values of arbitrary types" in any programming language (happy to be pointed to examples I am unfamiliar with, if someone has created one), so I don't think this is a Java-specific issue.