This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-01-24
Channels
- # aleph (13)
- # announcements (3)
- # beginners (134)
- # calva (9)
- # clojure (33)
- # clojure-europe (19)
- # clojure-nl (2)
- # clojure-norway (42)
- # clojure-uk (7)
- # clojurescript (43)
- # core-async (7)
- # core-typed (2)
- # cursive (32)
- # datomic (19)
- # fulcro (5)
- # gratitude (4)
- # hyperfiddle (26)
- # introduce-yourself (1)
- # jobs-discuss (15)
- # lsp (3)
- # malli (20)
- # off-topic (18)
- # overtone (3)
- # polylith (24)
- # squint (22)
- # xtdb (21)
Hi guys I am getting the following error when trying to read an email field from edn using the clojure.edn/read-string function
Invalid constituent character: @
does anyone have an idea how I can fix this?
my edn looks like this
{
"env-details" {:email ""
:password "userpassword"}
}
code looks like
(defn get-user-data [payload type]
(cond (= type :edn) (edn/read-string payload)
:else payload))
read-string
reads a string expecting to find EDN data in that string.
user
in EDN would be a valid symbol.
is not a valid name for anything.
You need to turn it from a symbol into a string. A correct EDN string representation of a string with an email would be "\"
.
But if you know that it's always a string and you already have the outer data deserialized, just don't use EDN at all at that level - store the value as a regular string.
I’m not sure the problem is in fact that
is an invalid symbol… it looks like a string to me, in that payload
example.
In fact I tested out the above function and payload myself and it succeeded with no errors:
(require '[clojure.edn :as edn])
(let [payload "{\"env-details\" {:email \"\"
:password \"userpassword\"}}"
type :edn
f (fn get-user-data [payload type]
(cond
(= type :edn) (edn/read-string payload)
:else payload))]
(f payload type))
result: {"env-details" {:email "" :password "userpassword"}}
I’m not sure what’s causing the error, but I suspect that perhaps the problem is that the value you are passing in as payload
is not in fact a valid EDN string, even though the example you pasted is.Does anyone know of any existing parsers for ISO8601 https://en.wikipedia.org/wiki/ISO_8601#Time_intervals? Either in Java or Clojure? Or any other language for that matter?
If you’re not aware of them, you can define periods of time in ISO8601 by saying <INSTANT_START>/<INSTANT_END>
or <INSTANT_START>/<PERIOD_TILL_END>
e.g. 2024-01-01T13:00:00Z/P1Y
for the year between 1pm on 2024-01-01 and 1pm on 2025-01-01.
You can also define an end instant, and specify a period before it, and there are various other short hand syntaxes.
Unfortunately java.time
doesn’t support the syntax; but does have partial support for some subsets of the syntax. Obviously ISO8601 instants are fully supported, but java.time.Duration
and java.time.Period
support only subsets i.e. time based syntax, or date based syntax, but not either or both.
Whilst https://juxt.github.io/tick/#_intervals, and Allen’s interval algebra, which is cool, it doesn’t provide any parsers for this sort of thing.
Maybe https://github.com/MenoData/Time4J? From https://stackoverflow.com/a/44622763/564509:
// case 1 (start/end)
System.out.println(MomentInterval.parseISO("2012-01-01T14:15Z/2014-06-20T16:00Z"));
// output: [2012-01-01T14:15:00Z/2014-06-20T16:00:00Z)
// case 1 (with some elements missing at end component and different offset)
System.out.println(MomentInterval.parseISO("2012-01-01T14:15Z/08-11T16:00+00:01"));
// output: [2012-01-01T14:15:00Z/2012-08-11T15:59:00Z)
// case 1 (with missing date and offset at end component)
System.out.println(MomentInterval.parseISO("2012-01-01T14:15Z/16:00"));
// output: [2012-01-01T14:15:00Z/2012-01-01T16:00:00Z)
// case 2 (start/duration)
System.out.println(MomentInterval.parseISO("2012-01-01T14:15Z/P2DT1H45M"));
// output: [2012-01-01T14:15:00Z/2012-01-03T16:00:00Z)
// case 3 (duration/end)
System.out.println(MomentInterval.parseISO("P2DT1H45M/2012-01-01T14:15Z"));
// output: [2011-12-30T12:30:00Z/2012-01-01T14:15:00Z)
// case 4 (duration only, in standard ISO-format)
Duration<IsoUnit> isoDuration = Duration.parsePeriod("P2DT1H45M");
// case 4 (duration only, in alternative representation)
Duration<IsoUnit> isoDuration = Duration.parsePeriod("P0000-01-01T15:00");
System.out.println(isoDuration); // output: P1M1DT15H
Thanks, I had stumbled on this, but for some unknown reason dismissed it — it looks like it should do the job nicely. 🙇
Hello everyone! Is this behaviour expected?
(with-redefs [inc #(* 2 %)] (inc 5))
;; => 6
(with-redefs [inc #(* 2 %)] (let [f inc] (f 5)))
;; => 10
Why the redef is ignored in the first case?Try
(println inc)
; #object[clojure.core$inc 0xd011f98 clojure.core$inc@d011f98]
; nil
(with-redefs [inc #(* 2 %)] (println inc))
; #object[sci.impl.fns$fun$arity_1__1168 0x2e9fd540 sci.impl.fns$fun$arity_1__1168@2e9fd540]
; nil
(with-redefs [inc #(* 2 %)] (let [f inc] (println f)))
; #object[sci.impl.fns$fun$arity_1__1168 0x676362d1 sci.impl.fns$fun$arity_1__1168@676362d1]
; nil
Different objects are referred to by inc
in the three cases.
Could it be due to clojure core library having been compiled with direct linking?
See: https://clojure.org/reference/compilationWhy wouldn't those be different, regardless of the linking? You're printing different functions, so you're getting different results.
Could depend upon different rules for dereferencing inc
, depending upon whether it is used as the function in a form, or as a regular variable to be evaluated?
Dereferencing is the same. In the case of (inc 5)
there's no dereferencing, there's inlining.
Because inc
has inlining metadata:
(defn inc
"Returns a number one greater than num. Does not auto-promote
longs, will throw on overflow. See also: inc'"
{:inline (fn [x] `(. clojure.lang.Numbers (~(if *unchecked-math* 'unchecked_inc 'inc) ~x)))
:added "1.2"}
[x] (. clojure.lang.Numbers (inc x)))
Just confirming here that the difference is inlining
Cool! Thank you @U064X3EF3
When writing a custom core.cache for use with core.memoize, I'm confused as to where the RetryingDelay enters the picture and why I don't see delays and derefs within the caches provided by core.cache
According to the comments RetryingDelay prevents your cache from caching an exception instead opting to retry the function. So it seems the API wraps your function in the RetryingDelay, which is what this private function here does by calling d-lay. From what I understand in the core.memoize API, you should be able to reify the CacheProtocol and pass it to memoizer to create your memoized cacher.
(defn- through*
"The basic hit/miss logic for the cache system based on `core.cache/through`.
Clojure delays are used to hold the cache value."
[cache f args item]
(clojure.core.cache/through
(fn [f _] (d-lay #(f args))) ;; RetryingDelay
#(clojure.core/apply f %)
cache
item))
As for why it's not included with core.cache, I think the readme explains the motivation:
Caches are generally immutable and should be used in conjunction with Clojure's state management, such as atom. SoftCache is the exception here, built on top of mutable Java collections, but it can be treated as an immutable cache as well.
RetryingDelay are stateful.np; You shouldn't be writing RetryingDelay per se, it should be ephemeral. The private functions in core.memoize will wrap whatever function is cached in your memoizer in the RetryingDelay before dispatching on CacheProtocol type you defined when the memoizer atom is updated. So you should be able to just do something like (memoizer expensive-function MyCustomCache)
and then wrap that in a function like memo
from core.memoizer