clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
Samuel McHugh 2020-12-15T10:38:06.034600Z

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

Samuel McHugh 2020-12-15T10:40:12.035400Z

Could it have to do with arbitrary chunking differences?

lukas.rychtecky 2020-12-15T10:41:47.035500Z

The numbers are Long

lukas.rychtecky 2020-12-15T10:42:32.035700Z

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

πŸ™Œ 1
Samuel McHugh 2020-12-15T10:42:33.035900Z

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

lukas.rychtecky 2020-12-15T10:44:52.036200Z

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 πŸ˜„

tomd 2020-12-15T11:46:55.038400Z

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?

borkdude 2020-12-15T11:54:36.038900Z

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

tomd 2020-12-15T11:56:18.039600Z

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

borkdude 2020-12-15T11:56:47.039800Z

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

tomd 2020-12-15T12:01:34.040300Z

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

murtaza52 2020-12-15T14:31:40.044700Z

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 #".*(\?|\*)?"

tomd 2020-12-15T14:34:56.044900Z

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

murtaza52 2020-12-15T14:42:02.045100Z

thanks

πŸ‘ 1
murtaza52 2020-12-15T14:48:52.045600Z

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

murtaza52 2020-12-15T14:49:21.045800Z

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

valerauko 2020-12-15T15:02:20.046Z

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

murtaza52 2020-12-15T15:03:06.046200Z

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

tomd 2020-12-15T16:12:53.046500Z

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}? ?

murtaza52 2020-12-15T16:13:58.046700Z

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

tomd 2020-12-15T16:20:48.046900Z

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

murtaza52 2020-12-15T16:22:41.047100Z

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

tomd 2020-12-15T16:24:41.047300Z

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

murtaza52 2020-12-15T16:25:24.047600Z

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

murtaza52 2020-12-15T16:25:36.047800Z

I want abc to match too

tomd 2020-12-15T16:26:12.048Z

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

tomd 2020-12-15T16:26:27.048200Z

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

tomd 2020-12-15T16:27:27.048500Z

(edited - sorry for inital typo)

murtaza52 2020-12-15T16:30:08.048800Z

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

tomd 2020-12-15T16:31:24.049Z

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

murtaza52 2020-12-15T16:31:44.049200Z

yup

murtaza52 2020-12-15T16:32:31.049400Z

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

murtaza52 2020-12-15T16:32:44.049600Z

I had just copy/pasted your expression

tomd 2020-12-15T16:37:38.049900Z

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

valerauko 2020-12-15T16:39:52.050100Z

Yeah that matches in my environments too

valerauko 2020-12-15T16:58:41.052Z

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-himik 2020-12-15T17:09:51.053300Z

And Clojure CLR.

2020-12-15T17:10:03.053500Z

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 Douglass 2020-12-15T17:10:43.053800Z

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

2020-12-15T18:24:07.054300Z

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.

πŸ‘ 1
kpav 2020-12-15T18:26:34.054500Z

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

2020-12-15T18:27:42.054800Z

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

valerauko 2020-12-15T18:35:26.055900Z

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

2020-12-15T19:40:11.056100Z

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

2020-12-15T19:42:11.056400Z

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

2020-12-15T19:43:05.058Z

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

2020-12-15T19:43:18.058200Z

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

2020-12-15T19:43:33.058400Z

there is no spec, people just imitate features they like

βœ… 1
2020-12-15T19:53:59.058700Z

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

2020-12-15T19:55:34.059Z

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.

2020-12-15T19:57:46.059300Z

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

2020-12-15T19:57:59.059500Z

If not, its just a Clojure-like

2020-12-15T20:05:36.059700Z

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.

2020-12-15T20:06:39.059900Z

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

2020-12-15T20:09:16.060100Z

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.

2020-12-15T20:22:33.060300Z

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

2020-12-15T20:23:33.060500Z

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

2020-12-15T20:23:42.060700Z

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.

2020-12-15T20:24:18.060900Z

that's fair, I misread you

2020-12-15T20:25:59.061100Z

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

2020-12-15T20:28:08.061400Z

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.

2020-12-15T20:32:43.061700Z

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.

2020-12-15T20:34:20.061900Z

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

2020-12-15T20:35:34.062100Z

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

2020-12-15T20:35:58.062400Z

Babashka, Joker and Clojerl do

2020-12-15T20:36:53.062600Z

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

2020-12-15T20:38:48.062800Z

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

2020-12-15T20:44:31.063200Z

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.

seancorfield 2020-12-15T21:22:37.065Z

@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?

seancorfield 2020-12-16T18:12:22.104700Z

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 😞

mpenet 2020-12-16T18:13:34.104900Z

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

1
seancorfield 2020-12-15T21:33:09.065100Z

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 πŸ™‚

kwladyka 2020-12-15T22:04:55.066700Z

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?

kwladyka 2020-12-15T22:39:23.067Z

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.

kwladyka 2020-12-15T22:47:25.068Z

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