Fork me on GitHub
#clojure
<
2020-12-15
>
Samuel McHugh10:12:06

I'm seeing some strange behavior regarding .lastIndexOf . My example is a bit contrived but I'm still curious what is going on here.

lukas.rychtecky10:12:47

The numbers are Long

lukas.rychtecky10:12:32

So when you call .lastIndexOf you search for (Long. 0) instead of (Integer. 0) .

🙌 3
Samuel McHugh10:12:33

Aha, you mean the ones present in y. Thanks that makes sense.

lukas.rychtecky10:12:52

I think the problem is that it uses low-level Java API, so there is no implicit coercion between types. That’s my tip, I could be wrong 😄

noisesmith19:12:11

yeah, in general it is useful to always use Long and Double (rather than Int or Float), here I'd usually use Long/parseLong

Samuel McHugh10:12:12

Could it have to do with arbitrary chunking differences?

tomd11:12:55

I'm looking at tidying up some requires, and I'm doing some nesting (aka "Prefix Lists") and noticed that require's docstring says "After removing the prefix, the names that remain must not contain any periods." Which means I can't nest as much as I'd like. Why is this, and could this be changed?

borkdude11:12:36

@tomd fwiw, nested libspecs are not recommended in the community style guide.

tomd11:12:18

ah that's good to know. I'm not sure I would agree, but I'd rather be consistent with that

borkdude11:12:47

sorry, I got it wrong. it's in a blog from Stuart Sierra. Just an opinion but maybe interesting to read: https://stuartsierra.com/2016/08/27/how-to-ns

tomd12:12:34

yeah I see his point. there is no inherent hierarchy. but often there is an implicit semantic hierarchy... I'm not sure I have a strong opinion on this actually

murtaza5214:12:40

this is a more of regex question - I am trying to match either abc or abc* or abc? How do I write a regex for it ? the following code will match only abc - (re-find #".*(\?|\*)" "abc*") . this regex also doesnt work #".*(\?|\*)?"

tomd14:12:56

#"abc[*?]?" should do it

murtaza5214:12:02

thanks

👍 3
murtaza5214:12:52

@tomd the reason I had used grouping is bcoz there can also be {..} after abc - (re-find #"\A.*?(\?|\*|\{.*?\})" "abc{cde}")

murtaza5214:12:21

your regex will match * ? , but I am not sure how to put {..} inside a character class

valerauko15:12:20

Do you want to match that {cde} as well?

murtaza5215:12:06

@UAEH11THP that could be anything {.*?} , I dont need to match it.

tomd16:12:53

When you say "there can also be {..} after abc" do you mean you would want to match abc{cde} and abc{cde}* and abc{cde}? ?

murtaza5216:12:58

nope it can either be abc or abc* or abc? or abc{abc}

tomd16:12:48

then I think your use of parens is good: (re-find #"abc(?:\?|\*|\{.*\})" "abc{cde}") will return abc{cde} which is what you want. I put the ?: at the start of the group to make it non-capturing because you don't care about its contents

murtaza5216:12:41

the problem is with abc case, that doesnt get matched, all others get matched

tomd16:12:41

sorry, i'm not understanding. give me an example of something which matches which shouldn't

murtaza5216:12:24

(re-find #"abc(?:\?|\*|\{.*\})" "abc") doesnt work

murtaza5216:12:36

I want abc to match too

tomd16:12:12

ah. sorry. then you just need an * after the parens

tomd16:12:27

(re-find #"abc(?:\?|\*|\{.*\})*" "abc{cde}")

tomd16:12:27

(edited - sorry for inital typo)

murtaza5216:12:08

the above gives nil, I had tried earlier (re-find #"abc(?:\?|\*|\{.*\})?" "abc{cde}") but that also did not work

tomd16:12:24

On JVM clojure? Cos I'm getting a match.

murtaza5216:12:31

hey sorry (re-find #"abc(?:\?|\*|\{.*\})*" "abc") this doesnt match

murtaza5216:12:44

I had just copy/pasted your expression

tomd16:12:38

I can only assume there's something different about your setup. It works for me in two separate clojure envs. And the regex works on http://regexr.com

valerauko16:12:52

Yeah that matches in my environments too

valerauko16:12:41

How does Clojure officially feel about implementations on other platforms, like BEAM or Rust? Personally I'd love to see Clojure become able to utilize the power of non-JVM environments too (also there's CLJS for precedent)

p-himik17:12:51

And Clojure CLR.

curlyfry17:12:03

Clojure CLR is listed on the official website so I'd say it's pretty embraced https://clojure.org/about/clojureclr It's used in https://arcadia-unity.github.io/ to make Unity games in Clojure

Darin Douglass17:12:43

there's also this unofficial rust implementation: https://github.com/clojure-rs/ClojureRS that seems fairly active

andy.fingerhut18:12:07

Clojure isn't a person, and doesn't feel 🙂. More seriously, if you are asking "How does Rich Hickey feel about Clojure implementations on other platforms?" then I think he is happy to see people create them if they want to do so. I believe he has a trademark in the USA on the name Clojure, so legally you cannot call something Clojure unless he approves, but you can always call such a project something else, and say it is inspired by Clojure.

👍 3
kpav18:12:34

There is hy https://github.com/hylang/hy which is almost clojure in python

hlolli18:12:42

or some of the MAL (make a lisp) implementations. Perhaps you should take the MAL challenge for BEAM and/or Rust @UAEH11THP, I did it (for totally different platform actually), and was eye opening task to do.

valerauko18:12:26

I saw Clojerl and Clojure-RS which is what made me think in the first place

noisesmith19:12:11

if pixielang counts, also check out fennel (both are aesthetically like clojure, but without the laziness and immutability)

Mattias19:12:05

Does Clojure have a specification, or just an implementation to imitate? What makes a Clojure Clojure?

noisesmith19:12:18

the common issue that comes up when trying to do "clojure on {my-platform}" is that clojure is extremely demanding of the garbage collector, and most vms garbage collectors are not good enough to make it usable

noisesmith19:12:33

there is no spec, people just imitate features they like

3
didibus19:12:59

While it doesn't have a Spec, it has a reference and a unit test kit. I think anything which uses the same syntax, has the same special forms, and brings in all of Clojure core (or a subset) would be a proper Clojure

didibus19:12:34

Anything which uses the Clojure syntax but not the same special forms and doesn't use the same core (or a subset of it), thus having different semantics would be a Clojure like or inspired language, but not a proper Clojure.

didibus19:12:46

Basically, if you can write a library in cljc that works portably between your Clojure and Clojure JVM, I'd say its a proper Clojure implementation

didibus19:12:59

If not, its just a Clojure-like

noisesmith20:12:36

I think you are making it sound much more clear cut than it is, for example cljs macros only work if they come from another compilation unit, and clojure on the jvm doesn't have compilation units. cljc is featureful enough to make a lot of messy things work if you have the patience.

noisesmith20:12:39

(alternatively it is as clear as you say, but you are wrong about cljc, and cljs is not a clojure?)

noisesmith20:12:16

also I'm considering (but not yet sold on) the idea that clojure is fundamentally about adopting the platform, and new clojures should be different in ways that accommodate / leverage the unique features of other platforms.

didibus20:12:33

What do you mean? cljs would meet my definition no?

noisesmith20:12:33

defmacro was my counter example, but there are other differences - oh you said "or some subset of it"

didibus20:12:42

And even if cljc can accommodate a lot, to me, if the new implementation choose to support cljc, it clearly shows its trying to be as compatible with Clojure JVM as it can.

noisesmith20:12:18

that's fair, I misread you

didibus20:12:59

Ya, I mean, that's my personal line in the sand, but obviously, there's many places you could choose to draw it.

didibus20:12:08

But I find this one pretty good. Cause for me, if a language pop-ups and says they're a Clojure. Fundamentally, I expect that it'll be very familiar to me, same syntax with similar semantics, same core functions mostly, and that it would even be possible to make a program written in it portable to other Clojure implementations (even if you might need some impl specific parts), which cljc is the Clojure mechanism for.

didibus20:12:43

And if its a Clojure-like, generally, it will just share syntax, but semantics and most core special forms and syntax could differ, and it makes no effort to be portable with other Clojure impls. Like Fennel for example.

didibus20:12:20

Most Clojure-like are actually Lisps who like the reader literals Clojure added by default. But have very little else in common.

noisesmith20:12:34

right, I can't think of a clojure or clojure-like outside clj/clj-clr/cljs that actually does the persistent data structures or laziness

didibus20:12:58

Babashka, Joker and Clojerl do

didibus20:12:53

So I'd say those 6 are the ones I know which would be proper Clojure, and that are also usable

didibus20:12:48

The one I'm not sure where to classify is Ferret. Because, you can take a lot of Clojure code that only uses the computation (no IO) parts of Clojure core, and it'll work on it directly. But, targeting no GC C++11 is so different, that I don't know if you can count it a Clojure. I also don't think it has any support for cljc, so I might say it is not a Clojure proper

didibus20:12:31

Clojerl and Babashka have cljc support, so does Clojure-clr, and ClojureScript that I know for sure. So I think those are the most proper Clojure alternate implementations out there. The rest of them are on a much more fuzzy spectrum, which I think can't be used to write portable libraries or programs, but you might be able to reuse a lot of your knowledge of Clojure and some code copy/pasted between them might even work. Those would be Fennel, Ferret, Lux, Carp, Rackjure, Janet, etc.

valerauko07:12:04

I had no idea there were so many

seancorfield21:12:37

@mpenet I have a question about exoscale/coax when you're around: for coercion of strings to keywords, it would be ideal (for us) if we could have it convert strings to lowercase as part of that. Is there an easy way to tell coax to do that?

seancorfield21:12:09

Somewhat answering my own question, if I pass this as the opts, it does what I want:

{::c/idents {`keyword? (fn [s _] (keyword (str/lower-case s)))}}
I'm a bit surprised that works with non-string input like 42 and even {:FOO 42} but I'm pleased that it does 🙂

mpenet06:12:24

Yes you can teach it not to try to coerce the value, by returning :exoscale.coax/invalid, in that case it will just leave the value passed untouched and you can let it blow up when you validate. In general it is good to add some checks on what the expected input is in the coercer fn, like cond string? etc etc... (about invalid, it's useful to differentiate know about impossible coercion internally sometimes, like with s/or. coax tries hard to never do any s/valid? call to do coercion, it does just one thing and with as little "code dependency" as possible, so we must have this possible return value on coercers otherwise I cannot differentiate between a coercer that just returns the input untouched because it's wrong or because it was acceptable in current form).

mpenet06:12:54

Also on the repl be aware of coercers caching (we cache the coercer fn returned for a spec form/key, so you pay for spec parsing only once per spec) , you ll have to turn it off not to have surprises https://github.com/exoscale/coax#caching

mpenet06:12:43

I should put a big bold warning about this on the readme

seancorfield18:12:22

Thanks @mpenet! I'm pleased with the changes to our codebase so far, but I have a couple of gnarly places where decomplecting the coercion and the validation is going to be harder than I thought 😞

mpenet18:12:34

Glad you like it. Feel free to ask if you have questions.

3
kwladyka22:12:55

Does anyone have log4j2 example of custom layout like here https://blog.10pines.com/2020/03/02/log-custom-json-with-log4j2/ but in Clojure? I want to generate custom JSON and this is not possible with com.fasterxml.jackson.dataformat/jackson-dataformat-yaml. Or maybe I should just do it in Java, should I?

kwladyka22:12:23

I tried to use https://github.com/joelcamera/log-custom-json-log4j2/tree/master/src/main/java/com/tenpines/logcustomjsonlog4j2/logs

(:import (org.apache.logging.log4j Logger LogManager)
           (api CustomLayout CustomMessage))
Syntax error (ClassNotFoundException) compiling at (src/api/logs.clj:1:1).
api.CustomLayout
package api;

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.layout.AbstractStringLayout;

import java.nio.charset.Charset;

@Plugin(name = "CustomLayout", category = "Core", elementType = "layout", printObject = true)
public class CustomLayout extends AbstractStringLayout {

    private static final String DEFAULT_EOL = "\r\n";

    protected CustomLayout(Charset charset) {
        super(charset);
    }

    @PluginFactory
    public static CustomLayout createLayout(@PluginAttribute(value = "charset", defaultString = "UTF-8") Charset charset) {
        return new CustomLayout(charset);
    }

    @Override
    public String toSerializable(LogEvent logEvent) {
        return logEvent.getMessage().getFormattedMessage() + DEFAULT_EOL;
    }
}
What I miss to use Java files in Clojure here? I guess this is about .class files, but no idea how to make it work.

kwladyka22:12:25

Anyway I want to rewrite this to Clojure probably, which looks hard. That is why I would appreciate an example of something similar :)