Anonymous methods in common lisp - methods

I want to save a generic function as a variable:
(defvar *gf* (make-instance 'standard-generic-function)
But when adding a method I have to define call-next-method and next-method-p myself:
(add-method *gf*
(make-instane 'standard-method
:function (lambda (args next-methods)
(flet ((call-next-method () ...)
(next-method-p () ...))
(apply (lambda () ...) args)))))
How do I call a method to define call-next-method?
Is there a simpler way to do this?

See MAKE-METHOD-LAMBDA.
If you Google for it, you will find various informations about the function. For example MAKE-METHOD-LAMBDA considered harmful.

Related

Clojure: Conditionally call a function and rest of the other functions by default

I want to execute a function conditionally and rest of the other functions by default irrespective of the first condition being true or false.
Ex: `
(defn- publish
[txn publisher domain-slug template first-published-at]
(if (= 2 2) (do (somefunc txn publisher)))
(firstfunc txn publisher domain-slug first-published-at)
(secondfunc txn publisher)
)
`
I want to execute all the three functions if true and execute the last two functions if false.
when is intended to be used used for conditional side-effects. e.g.
(defn- publish
[txn publisher domain-slug template first-published-at]
(when (= 2 2)
(somefunc txn publisher))
(firstfunc txn publisher domain-slug first-published-at)
(secondfunc txn publisher))
You can try
(cond
(= 2 2) (some-fn arg1 arg2)
:else (firstfunc txn publisher domain-slug first-published-at)
(secondfunc txn publisher))
Refer here https://clojuredocs.org/clojure.core/cond
for syntax

shared library method definition with Map

I checked few jenkins shared library examples and I found that in some of them the call method define as below:
def call (Map parameters) { .... }
and in other:
def call (Map parameters = [:]) { .... }
What is the difference between definition of parameters with =[:] and without it ?
Groovy supports a feature feature is called default arguments
The first example requires you to pass in a value for the parameter.
call(['key': 'value'])
The second example can be called that way, but it can also be called without specifying a value and it will use the default:
call()

How to call a function (requiring args) with string name - Clojurescript | d3

I'm trying to do some refactoring on a function (set-attr) that calls a function (.attr) on a d3 object (node). I want to be able to decouple the object function (.attr) from set-attr.
But I keep getting this error Cannot read property 'each' of null.
I'm hoping someone has experience with d3 interop in Cljs and knows of something that can work, because it works fine on regular js objects.
Function that works
(defn set-attr [node [attr settr]]
(.attr node attr settr))
What I think should work (but gives me the error)
(defn set-attr [node [attr settr]]
((aget node "attr") attr settr))
Works fine on a regular js object
((aget (clj->js {:foo (fn [x y] (str "hi" x y))}) "foo" ) "ryan" "lol")
;; => "hiryanlol"
d3 uses inheritance. Thus you cannot process this object as a mere hash-table. You have to reach to its prototype to get what you want, which is usually not a good idea: this would produce rather brittle code.

Why the need to call resolve()?

I am looking at an example of Reason at A First Reason React app for Javascript developers
And I see that he is calling Js.Promise.resolve when using bs-fetch:
RepoData.fetchRepos()
|> Js.Promise.then_(repoData => {
handleReposLoaded(repoData);
Js.Promise.resolve();
})
|> ignore;
I have seen similar code in BuckleScript code as well. For example in Bucklescript Cookbook:
Js.Promise.(
Fetch.fetch "https://api.github.com/users/reasonml-community/repos"
|> then_ Fetch.Response.text
|> then_ (fun text ->
text
|> names
|> Array.iter Js.log
|> resolve)
|> ignore
In JS we usually call resolve when we create a new promise, not when using a function that returns a promise. So why do we need to call resolve in the cases above?
Js.Promise.then_ requires that a new promise is returned.
The reason is that es6 promises aren't soundly typed. The value returned in a then callback is dynamically either wrapped or (infinitely) flattened so that it always returns a promise, and never a nested promise. That means if we allow any value to be returned (let then_: ((_ => 'a), Js.Promise.t(_)) => Js.Promise.t('a)), and if that value is a promise ('a = Js.Promise.t('b)), it would have the return type Js.Promise.t(Js.Promise.t('b)), but the value returned will actually have been flattened to just a Js.Promise.t('b).
Having then_ accept only a promise from the callback alleviates this a bit by making it more obvious that you return a nested promise. It's still possible to resolve a promise however, so the type is still not sound, but it makes it a little bit harder to shoot yourself in the foot.
There will be a sound and elegant promise API in the (probably near) future, but since it's a non-trivial task to design and implement it'll take a bit of time to get it right.

How could I specify a function that can accept any type exclude one type in typed/racket?

I mean, just like annotate a function as
(: function (-> (Not String) String))
I know this doesn't work, is there a way to achieve it?

Resources