What is an alternative to <!! in cljs? - asynchronous

a go block returns a channel and not the return value, so how can one extract the return value in a go block, when cljs doesn't have <!!?
For example, given the following code:
(go (let [response (<! (http/get "https://api.github.com/users"
{:with-credentials? false
:query-params {"since" 135}}))]
(:status response)))
will return a channel but not (:status response). How to make this go block return a (:status response)?

<!! doesn't exist in javascript because the runtime does not support it. Javascript is single-threaded and <!! is a blocking operation. Blocking the main thread in a browser-based environment is a bad idea as it would simply freeze all javascript actions (and potentially freeze the whole page) until unblocked.
Instead, consider using clojure.core.async/take! like so:
(take! channel (fn [value] (do-something-with value)))

Related

If generic functions work well alone, what is the value of defclass?

I read a lot about generic functions in CL. I get it. And I get why they are valuable.
Mainly, I use them for when I want to execute a similar action with different data types, like this:
(defgeneric build-url (account-key)
(:documentation "Create hunter api urls"))
(defmethod build-url ((key number))
"Build lead api url"
(do-something...))
(defmethod build-url ((key string))
"build campaign api url"
(do-somthing... ))
In this example, campaign-url and lead-url are structures (defstruct).
My question is, at a high level, how do classes add value to the way generic functions + structures work together?
Structures historically predate classes, are more restricted and more "static" than classes: once a structure is defined, the compiler can generate code that accesses its slots efficiently, can assume their layout is fixed, etc. There is a lot of inlining or macro-expansion done that makes it necessary to rebuild everything from scratch when the structure changes. Being able to redefine a struct at runtime is not something defined by the standard, it is merely implementations trying to be nice.
On the other hand, classes have more features and are easier to manipulate at runtime. Suppose you write this class:
(defclass person ()
((name :initarg :name :reader .name)))
And you instantiate it:
(defparameter *someone* (make-instance 'person :name "Julia O'Caml"))
It is possible now to update the class definition:
(defparameter *id-counter* 0)
(defun generate-id ()
(incf *id-counter*))
(defclass person ()
((name :initarg :name :reader .name)
(dob :initarg :date-of-birth :reader .date-of-birth)
(%id :reader .id :initform (generate-id))))
And now, *someone*, which existed already, has two additional fields, dob that is unbound, and %id that is automatically initialized to 1. There is a whole section about Object Creation and Initialization (7.1) that defines how objects can be redefined, change class, etc.
Moreover, this mechanism is not fixed, a lot of the steps described above rely on generic functions. It is possible to define how an object is allocated, initialized, etc. The concept was standardized as what is known as the Meta-Object Protocol, which also introduces the concept of metaobject, the object representing a class: usually a class has a name, parent classes, slots, etc. but you can add new members to a class, or change how instance slots are organized (maybe your just need a global handle and a connection, and the actual instance slots are stored in another process?).
Note also that once CLOS/MOP was defined, it was also eventually possible to define structures in this framework: in the standard , defstruct (without a :type option) defines classes with a structure-class metaclass. Still, they do not behave like standard-class because as said above they are more restricted, and as such are subject to more aggressive compilation optimizations (in general).
Structures are nice if you need to program like in C and you are ok with recompiling all your code when the structure changes. It is however premature optimization to use them in all cases. It is possible to use a lot of standard objects without noticing much slowness nowadays (a bit like Python).

Assigning Spotify window to a group in StumpWM

I am currently starting to set up stumpwm, and I would like to assign a specific window to a particular group.
So far I have this:
(define-frame-preference "Spotify"
(0 t t :class "Spotify")
)
So essentially, I would expect that that would set the windows with the class Spotify to the group Spotify, this however does not happen.
Can anybody help me on this?
Thank you!
The relationship between X11 windows and Linux processes is thin: things are asynchronous, you start a process and some time later zero, one or more windows are created.
You have to work with callbacks, there is no easy way to create a process and synchronously have all its windows in return.
Some processes are nice enough to set the _NET_WM_PID property on windows (it looks like the "Spotify" application does it). You can retrieve this property as follows:
(first (xlib:get-property (window-xwin w) :_net_wm_pid))
Placement rules cannot help here, given how Spotify fails to set the class property early enough (see comments and other answer). But you can use a custom hook:
STUMPWM-USER> (let ((out *standard-output*))
(push (lambda (&rest args) (print args out))
*new-window-hook*))
(#<CLOSURE (LAMBDA (&REST ARGS)) {101A92388B}>)
Notice how I first evaluate *standard-output* to bind it lexically to out, so that the function can use it as a stream when printing informations. This is because the hook might be run in another thread, where the dynamic binding of the standard output might not be the one I want here (this ensures debugging in done in the Slime REPL, in my case).
When I start for example xclock, the following is printed in the REPL:
(#S(TILE-WINDOW "xclock" #x380000A))
So I can change the hook so that instead if does other things. This is a bit experimental but for example, you can temporarily modify the *new-window-hook* to react on a particular window event:
(in-package :stumpwm-user)
(let ((process (sb-ext:run-program "xclock" () :search t :wait nil))
(hook))
(sb-ext:process-kill process sb-unix:sigstop)
(flet ((hook (w)
(when (find
(sb-ext:process-pid process)
(xlib:get-property (window-xwin w) :_net_wm_pid))
(move-window-to-group w (add-group (current-screen) "XCLOCK"))
(setf *new-window-hook* (remove hook *new-window-hook*)))))
(setf hook #'hook)
(push #'hook *new-window-hook*))
(sb-ext:process-kill process sb-unix:sigcont))
Basically: create a process, stop it to minimize race conditions, define a hook that checks if the PID associated in the client matches the one of the process, execute some rules, then remove the hook from the list of hooks. This is fragile, since if the hook is never run, it stays in the list, and in case of errors, it also stays in the list. At the end of the expression, the hook is added and the process resumes execution.
So it seems like, as pointed out by coredump, the are issues in the way the Spotify window is defined.
As an alternative, there are fortunately plenty of ways to control spotify via Third Party Clients (ArchWiki)
Personally, I found that you can control spotify via Ivy on Emacs thanks to this project
Ivy Spotify and this will probably be what I will use.

Clojure TCP Server with Aleph

I am attempting to write a simple TCP server using Aleph. Everything works fine, except I am unsure of how I should detect when a channel has been closed.
From the documentation:
When the client closes the connection, both sides of the channel will be immediately sealed. The final message from the channel will be nil
However, I never seem to receive this final nil message. If I inspect the channel, I do see that it has been closed. Here is my code:
(use 'lamina.core 'aleph.tcp 'gloss.core)
(defn process-msg [ch msg]
(if (closed? ch)
(println "Channel has been closed") ;This never happens
(do-some-processing msg)))
(start-tcp-server
(fn [ch client-info]
(receive-all ch
(partial process-msg ch))
{:port 10000, :frame (string :utf-8 :delimiters ["\n"])})
Should I be doing something differently? Is my frame keeping the nil message from being processed? I could have a separate thread monitoring my channels and checking whether or not they have been closed, but this seems like a poor design. I would prefer to use Aleph, but right now its looking like I will need to use a raw Netty handler. Using Netty directly would be fine, but I'd prefer to use Aleph if possible since it feels a little more idiomatic.
To register a callback for when a channel is closed or drained, use (on-closed ch callback) or (on-drained ch callback), which both take a callback with zero arguments.
https://github.com/ztellman/lamina/wiki/Channels

Do continuation record the PC and register states?

currently, when I am experimenting the continuation in functional languages, my understanding is that a continuation records the current program counter and register files, and when a continuation is returned, then the PC and the registered files will be restored to the values it has recorded.
So in the following dumb example from Might's blog post,
; right-now : -> moment
(define (right-now)
(call-with-current-continuation
(lambda (cc)
(cc cc))))
; go-when : moment -> ...
(define (go-when then)
(then then))
; An infinite loop:
(let ((the-beginning (right-now)))
(display "Hello, world!")
(newline)
(go-when the-beginning)) ; here the-beginning continuation passed to go-when, which ultimately will have an continuation applied to an continuation, that returns a continuation, which will cause the the program point resumed to the PC and registers states recorded in it.
I am not sure my understanding right.. Please correct me if you think it is not.....
Program counter and register files are not what the continuation records.
The best way to describe the meaning of call-with-current-continuation is that it records the program context. For instance, suppose you're evaluating the program
(+ 3 (f (call-with-current-continuation g)))
In this case, the context of the call-with-current-continuation expression would be
(+ 3 (f [hole]))
That is, the stuff surrounding the current expression.
Call-with-current-continuation captures one of these contexts. Invoking a continuation causes the replacement of the current context with the one stored in the continuation.
The idea of a context is a lot like that of a stack, except that there's nothing special about function calls in contexts.
This is a very brief treatment. I strongly urge you to take a look at Shriram Krishnamurthi's (free, online) book PLAI, in particular Part VII, for a more detailed and careful look at this topic.

How to change a Hunchentoot session cookie name by specializing a function?

I'm using Hunchentoot and would like to change the name of the session cookie. This is implemented with a generic function and the docs say to change the name you can "specialize the function".
I'm not really sure what this means here. I was under the impression that specializing a function is to dispatch a method on certain argument types. In this particular case, the function takes the server acceptor and I don't want to change that. Can someone illuminate me on this?
The API: http://weitz.de/hunchentoot/#session-cookie-name
Here's the implementation in the source:
(defgeneric session-cookie-name (acceptor)
(:documentation "Returns the name \(a string) of the cookie \(or the
GET parameter) which is used to store a session on the client side.
The default is to use the string \"hunchentoot-session\", but you can
specialize this function if you want another name."))
(defmethod session-cookie-name ((acceptor t))
"hunchentoot-session")
Make a subclass and specialize that way:
(defclass my-acceptor (hunchentoot:acceptor) ())
(defmethod session-cookie-name ((acceptor my-acceptor))
"my-session")
The function still takes an acceptor, it's just your kind of acceptor, now.

Resources