This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-08-24
Channels
- # announcements (6)
- # babashka (25)
- # beginners (52)
- # cherry (8)
- # cider (9)
- # clj-kondo (9)
- # clojure (44)
- # clojure-australia (5)
- # clojure-dev (4)
- # clojure-europe (8)
- # clojure-nl (5)
- # clojure-norway (3)
- # clojure-spec (3)
- # clojure-uk (1)
- # clojurescript (16)
- # conjure (1)
- # core-async (8)
- # cursive (11)
- # fulcro (13)
- # honeysql (6)
- # hyperfiddle (13)
- # jackdaw (1)
- # jobs (9)
- # lsp (13)
- # meander (5)
- # missionary (2)
- # off-topic (11)
- # polylith (11)
- # re-frame (2)
- # reitit (11)
- # shadow-cljs (69)
- # squint (23)
- # tools-deps (30)
- # xtdb (3)
I ported @armed’s hn-reader from cherry to clava including macros
https://github.com/borkdude/clava-hn-reader
based on a branch macro-experiment
(during a train ride with really bad internet so querying the API a zillion times was fun...)
https://github.com/clavascript/clavascript/pull/124 adds the ability to extend the JS iterable protocol to Clava types 🙂
ugh, there's no way to get the full arity of a function
fn.length
doesn't include rest parameters or parameters with defaults
so partial is super tricky
say you implemented it like this:
export function partial(fn, ...args) {
return function (...moreArgs) {
return fn(...args.concat(moreArgs));
};
}
this is fine when it's a pure function
> a = partial((x, y) => x + y, 1)
[Function (anonymous)]
> a(2)
3
it breaks things when the function is attached to an object because this
gets lost
> a = {y: 1, x: function(a, b){ return this.y + a + b}}
{ y: 1, x: [Function: x] }
> a.x(2, 3)
6
> partial(a.x, 2)(3)
NaN
there's no way to get at the original this
of a function once it's been passed in separate from its object
we could keep partial for pure functions and then include a bind function to allow manipulation of this
function bind(thisArg, fn, ...args) {
return fn.bind(thisArg, ...args);
}
> a = {y: 1, x: function(a, b){ return this.y + a + b}}
{ y: 1, x: [Function: x] }
> bind(a, a.x, 2)(3)
6
we could name that bind function partial but then you always have to pass in what this
will be even if you don't care what it is
> function partial(thisArg, fn, ...args) {
... return fn.bind(thisArg, ...args);
... }
undefined
> b = partial(null, (x, y) => x + y, 2)
[Function: bound ]
> b(3)
5
I think it makes sense to have separate functions for the pure function case and the object function case, so a partial
function for currying pure functions and a bind
function for currying object-bound functions (or applying a different thisArg
to a function than it originally had)
so it would end up being this:
export function partial(fn, ...args) {
return function (...moreArgs) {
return fn(...args.concat(moreArgs));
};
}
export function bind(thisArg, fn, ...args) {
return fn.bind(thisArg, ...args);
}
or perhaps just use bind with globalThis
export function partial(fn, ...args) {
return fn.bind(globalThis, ...args);
}
export function bind(thisArg, fn, ...args) {
return fn.bind(thisArg, ...args);
}
thoughts?