Updating an OM cursor that went through a function - clojurescript

When calling om/build, one can send an fn option, which according to the documentation:
`fn - a function to apply to x before invoking f.`
My question is, when applying om/transact! or om/update! to the cursor (x) that was manipulated by the fn, how does the original cursor get affected?

(om/build comp1 (f cursor)) has the same effect as (om/build comp1 cursor {:fn f})
So the answer is that it really depends what f does. As long as (f x) (or its content) is still a cursor, you can om/transact! or om/update! on it (or its content).
For example, if x is {:x 1} and f is #(update-in % [:x] inc), f will apply on the value of the cursor; the underlying atom will not change. When you om/transact! or om/update! on (f x) it'll operate on the atom inside cursor x. On the next render, you'll once again get (f x) based on the updated x.
On the other hand, if f makes x not a cursor (e.g. f is om/value), then you won't be able to om/transact! or om/update! on it at all.
Hope that helps.

Related

How can I make this function more elegant

I have the function:
wrap :: Text -> [Text] -> Text
wrap x = intercalate "" . map ((<> x) . (x <>))
The purpose of which is to wrap each element of a list with a given string and join them all together.
The brackets around the first argument to map annoy me, and so does the use of "". So I wonder is there a more elegant (or generic, I guess) way to express this function?
(Copied from my comment so the question can be marked as answered.)
You could use foldMap f instead of intercalate "" . map f. Note that intercalate "" is equivalent to Data.Text.concat.
Just to put my hat in the ring... Since the pattern is
xexxexxex
(where the es are placeholders for elements of the original list), another way you can build this output is by putting two xs between each element, and wrapping the bookends manually. So:
wrap x es = x <> intercalate (x <> x) es <> x
One small but nice feature of this rewrite is that for input lists of length n, this will incur only n+2 calls to (<>) rather than 3n-1 as in theindigamer's answer.

HTML Layout: mixing [Element] and [Signal Element] in an Elm web apge

I am reading about flow down and it's suppose to let us stack elements vertically on our web site. What are you supposed to do when when parts of your website are signals? I would picture a web site like this:
Introduction
Dynamic Component
More Static Text
The type of flow down: [Element] -> Element so I can't just mix in [signal Element] as I would like. In a previous solution I saw solutions involving lift so here's what I came up with:
import Random
main = column <~ (constant "5") ~ (Random.range 0 100 (every second))
column x y = flow down [asText x, asText y]
Here I just stack the number 5 on top of a randomly changing number. Perhaps it depends depends on the Window size,
import Random
import Window
main = column <~ (constant "5") ~ Window.dimensions
column x y = flow down [asText x, asText y]
Is this considered good practice or are there better ways of doing layout in Elm?
Extracting a non-signal function and lifting it is generally good practice. In this case you could also use Signal.Extra.combine : [Signal a] -> Signal [a] if you like:
main = flow down <~ combine [constant (asText "5"), asText <~ Window.dimensions]
As you can see, there is a lot more lifting going on than in your solution, just to get it into a one-liner. So I don't think it's ideal. But combine can be handy in other (more dynamic) situations.
Full disclosure: I'm the author of the library function that I linked to.
Up to date answer.
Either you use combine, which is now in the Signal-extra library or, for this simple case
column x y =
Signal.map (flow down) <|
Signal.map2 (\a b -> [a, b]) (show x) (show y)

How to prevent maxima to rewrite the output of 2*sqrt(2) to 2^(3/2)?

Maxima input of
2*sqrt(2)
by default returns the output
2^(3/2)
How can I get Maxima to just return 2*sqrt(2) ?
(I use this in the tex() function.)
To the best of my knowledge, there is no way to prevent Maxima from simplifying 2*sqrt(2) to 2^(3/2), with two probably-hard-to-use exceptions:
(1) Turn off simplification entirely. But that disables all simplifications, e.g. 1 + 1 simplifying to 2. But if you want to try it: just enter simp : false;.
(2) Disable the simplification sqrt(2) to 2^(1/2) via :lisp (setf (get '%sqrt 'operators) nil) But then Maxima for the most part doesn't know what to do with sqrt.
I don't recommend either one of these.
You can try something like
simp: false;
tex(2*sqrt(2));
block code...;
simp: true;
That way you don't have to disable the simplification permanently.
You can do this:
(%i1) matchdeclare(n_, integerp,m_, integerp)$
tellsimp(n_*sqrt(m_), n_*sqrt(box(m_)))$
and afterwards:
(%i3) 2*sqrt(2);
(%o3) 2 √2
(%i4) sqrt(3)*9;
(%o4) 9 √3
You'll notice that the number under the square root sign in the output is colored red, because of box(). But if you select the expression in wxMaxima, and then popup "Copy LaTeX", you'll get exactly what you want, e. g.
\[2\,\sqrt{2}\]
Unfortunately if you try tex(2*sqrt(2)) to get the TeX code, you'll get $$2\,\sqrt{\boxed{2}}$$instead.

Freefem++: Solving poisson equation with numerical function

I am using Freefem++ to solve the poisson equation
Grad^2 u(x,y,z) = -f(x,y,z)
It works well when I have an analytical expression for f, but now I have an f numerically defined (i.e. a set of data defined on a mesh) and I am wondering if I can still use Freefem++.
I.e. typical code (for a 2D problem in this case), looks like the following
mesh Sh= square(10,10); // mesh generation of a square
fespace Vh(Sh,P1); // space of P1 Finite Elements
Vh u,v; // u and v belongs to Vh
func f=cos(x)*y; // analytical function
problem Poisson(u,v)= // Definition of the problem
int2d(Sh)(dx(u)*dx(v)+dy(u)*dy(v)) // bilinear form
-int2d(Sh)(f*v) // linear form
+on(1,2,3,4,u=0); // Dirichlet Conditions
Poisson; // Solve Poisson Equation
plot(u); // Plot the result
I am wondering if I can define f numerically, rather than analytically.
Mesh & space Definition
We define a square unit with Nx=10 mesh and Ny=10 this provides 11 nodes on x axis and the same for y axis.
int Nx=10,Ny=10;
int Lx=1,Ly=1;
mesh Sh= square(Nx,Ny,[Lx*x,Ly*y]); //this is the same as square(10,10)
fespace Vh(Sh,P1); // a space of P1 Finite Elements to use for u definition
Conditions and problem statement
We are not going to use solve but we ll handle matrix (a more sophisticated way to solve with FreeFem).
First we define CL for our problem (Dirichlet ones).
varf CL(u,psi)=on(1,2,3,4,u=0); //you can eliminate border according to your problem state
Vh u=0;u[]=CL(0,Vh);
matrix GD=CL(Vh,Vh);
Then we define the problem. Instead of writing dx(u)*dx(v)+dy(u)*dy(v) I suggest to use macro, so we define div as following but pay attention macro finishes by // NOT ;.
macro div(u) (dx(u[0])+dy(u[1])) //
So Poisson bilinear form becomes:
varf Poisson(u,v)= int2d(Sh)(div(u)*div(v));
After we extract Stifness Matrix
matrix K=Poisson(Vh,Vh);
matrix KD=K+GD; //we add CL defined above
We proceed for solving, UMFPACK is a solver in FreeFem no much attention to this.
set(KD,solver=UMFPACK);
And here what you need. You want to define a value of function f on some specific nodes. I'm going to give you the secret, the poisson linear form.
real[int] b=Poisson(0,Vh);
You define value of the function f at any node you want to do.
b[100]+=20; //for example at node 100 we want that f equals to 20
b[50]+=50; //and at node 50 , f equals to 50
We solve our system.
u[]=KD^-1*b;
Finally we get the plot.
plot(u,wait=1);
I hope this will help you, thanks to my internship supervisor Olivier, he always gives to me tricks specially on FreeFem. I tested it, it works very well. Good luck.
The method by afaf works in the case when the function f is a free-standing one. For the terms like int2d(Sh)(f*u*v), another solution is required. I propose (actually I have red it somewhere in Hecht's manual) an approach that covers both cases. However, it works only for P1 finite elements, for which the degrees of freedom are coincided with the mesh nodes.
fespace Vh(Th,P1);
Vh f;
real[int] pot(Vh.ndof);
for(int i=0;i<Vh.ndof;i++){
pot[i]=something; //assign values or read them from a file
}
f[]=pot;

Selection function comments while expanding in Lisp modes

I'm using a keyboard shortcut bound to:
er/expand-region, which is an interactive Lisp function in `expand-region-core.el'.
to expand the region.
For example when I want to select a function and move it around.
My problem is that if I want to select any function like, say:
;; some comment related to the function
(defn foo [x]
...)
I cannot "expand" to include ";; some comment". As soon as I expand more than the function (without the comment) it expends the full buffer.
While I'd like it to first expand to include the function and the comment and then the full buffer.
It's bothering me so much that I'm temporarily doing this as a workaround:
(defn foo [x]
;; some comment
...)
How can I modify er/expand-region (or another function) so that after expanding to the full function it expands the comments right above the function before expanding to the whole buffer?
From Magnar Sveen, the creator of the package expand-region, taken from his github:
Example:
Let's say you want expand-region to also mark paragraphs and pages in
text-mode. Incidentally Emacs already comes with mark-paragraph and
mark-page. To add it to the try-list, do this:
(defun er/add-text-mode-expansions () (make-variable-buffer-local
'er/try-expand-list) (setq er/try-expand-list (append
er/try-expand-list
'(mark-paragraph
mark-page))))
(add-hook 'text-mode-hook 'er/add-text-mode-expansions)
Add that to
its own file, and add it to the expand-region.el-file, where it says
"Mode-specific expansions"
Warning: Badly written expansions might slow down expand-region
dramatically. Remember to exit quickly before you start traversing the
entire document looking for constructs to mark.
I would say you could add "er/mark-paragraph" to the expand-region list, that should do it.
Following user Dualinity's advice, I added the following to clojure-mode-expansions.el (can be done for other modes than Clojure of course) :
;; added this line at the beginning of the file
(require 'org-mode-expansions)
Then I added the line er/mark-paragraph to the expand list inside the er/add-clojure-mode-expansions method:
(defun er/add-clojure-mode-expansions ()
"Adds clojure-specific expansions for buffers in clojure-mode"
(set (make-local-variable 'er/try-expand-list) (append
er/try-expand-list
'(er/mark-clj-word
er/mark-clj-regexp-literal
er/mark-paragraph ; added this line
er/mark-clj-function-literal))))
I restarted Emacs (not too sure as to what was needed to be sure it was taken into account so I restarted the whole thing).
And that's it: now expanding selects "outer" function comments too.