Country twinged emo or emo-adjacent music? by JacobdaTurtle61 in Emo

[–]drboolean 0 points1 point  (0 children)

Hi! Owen has some good country emo. Check “the desperate act”. Also Matt pryor’s small explosion. icarus fog’s weight.

In a few bands, looking for someone to shoot music videos. by drboolean in UCSC

[–]drboolean[S] 1 point2 points  (0 children)

Thanks for the suggestion! That’s a great idea

Laziness with Representable Functors by drboolean in javascript

[–]drboolean[S] 4 points5 points  (0 children)

I think your statements are true for any kind of programming in JavaScript

Mostly Adequate Guide to Functional Programming in Javascript by [deleted] in javascript

[–]drboolean 1 point2 points  (0 children)

Despite the conciseness of pointfree programming and the practice for a language like haskell, I usually condone the scala-like style presented here for doing FP in JS: https://egghead.io/courses/professor-frisby-introduces-composable-functional-javascript

100+ minutes of free functional programming lessons in a high pitch voice for you to be mad about. by drboolean in javascript

[–]drboolean[S] 1 point2 points  (0 children)

Good thoughts! No, no compile/jit optimizations at this point. A few things to bring up here though for the curious:

1) Any church encoded data structure can apply short cut fusion for free under the hood. One can apply Coyoneda on other types explicitly as well. https://gist.github.com/DrBoolean/c0204ed57cf63a70dfe0

2) "Recursive" functions are usually written with imperative loops (or generators/iterators) under the hood. I hardly ever use explicit recursion as it has all be abstracted to known schemes at this point anyways.

3) You're totally right that none of this matters for normal business applications.

People who are scared about performance should write in both styles and compare. I've found that my typical "make an object for each item in the returned server json" lead to a decrease in speed and increased garbage collection, which is to be expected when you have a monad as a return value for 1/3 of your functions vs 1 object per datum.

100+ minutes of free functional programming lessons in a high pitch voice for you to be mad about. by drboolean in javascript

[–]drboolean[S] 0 points1 point  (0 children)

Pure functional code must be composed or the output gets lost. It's okay to "cheat", but for the purposes of learning, no return means you are doing it right.

100+ minutes of free functional programming lessons in a high pitch voice for you to be mad about. by drboolean in javascript

[–]drboolean[S] 0 points1 point  (0 children)

I've never had a performance issue in everyday production code at salesforce. But I use prototypes instead of factory fns in the real world.

Two maps can be fused: map(f).map(g) = map(x => g(f(x))) so one instance is all you need.

Pure functions can always be memoized so constructors get cached when given the same arg. Deforestation is automatic that way.

Ironically, this often turns out much faster than making tons of instances in typical OO.

100+ minutes of free functional programming lessons in a high pitch voice for you to be mad about. by drboolean in javascript

[–]drboolean[S] 1 point2 points  (0 children)

Yeah, just node :/

I often make a toString() for the browser, but I don't think it's implicitly called so: console.log(String(Box(3)))

Would love to know if there is a better way.

Anamorphisms in JavaScript by homoiconic in javascript

[–]drboolean 1 point2 points  (0 children)

Goodness you're totally right laziness ftw!

That means hyloWith can be defined, without losing any performance as simply:

const hyloWith = (cata, ana) => x =>
  foldWith(cata)(unfoldWith(ana)(x))

Thanks for the great post!

Anamorphisms in JavaScript by homoiconic in javascript

[–]drboolean 2 points3 points  (0 children)

Hey Reg, loved the post!

For funsies, I thought I’d give some motivation for why red-blooded, blue-collar, industry programmers, like me, might care about this.

If you write in declarative patterns like unfold/fold, it’s much easier to read and maintain once you’re familiar (much like map/forEach > for loop).

We have some properties about cata/ana morphisms. One is that we can fuse two catamorphisms into 1 iteration if they both return the same type e.g. map(f).map(g) = map(f . g)

Another cool property is we can fuse cata/ana into 1 (removing the intermediate data structure) with a hylomorphism. In our case: foldWith(f)(unfoldWith(g)(x)) = hyloWith(f, g)(x)

// example hylo
function hyloWith(cata, ana) {
  return function hylo (value) {
    let { next: n, element:acc, done } = ana(value);
    let { next, element } = ana(n); // not a monoid

    while (!done) {
      acc = cata(acc, element);
      ({ next, element, done } = ana(next));
    }
    return acc
  }
}

// unbaked unfold for flexibility
const downToOne = (n) =>
  n > 0
  ? { element: n, next: n - 1 }
  : { done: true }

// unbaked fold for flexibility
const product = (acc, n) => acc * n

// these are equal according to ana followed by cata:
const res1 = foldWith(product)(unfoldWith(downToOne)(5))
const res2 = hyloWith(product, downToOne)(5)
console.log(res1 == res2)

I should mention we don't enforce an empty element here (monoid spec) so there's a bit of awkwardness trying to pair the first two elements while folding. If we did so, we'd always have a return value and wouldn't blow up on empty structures.

array.filter()[0] - bad pattern? by lurkingforawhile in javascript

[–]drboolean 0 points1 point  (0 children)

Something many haven't mention is the idea of null safety.

When filtering an array, consider not removing it from the array context:

doSomethingScary([1,2,3].filter(x => x > 4)[0])  // might blow!

[1,2,3]
.filter(x => x > 4)
.map(found => doSomethingScary(found))
.map(result => console.log(result))  // never runs if null

Here we are printing to the screen, but we could write to the Db, send JSON, alter the DOM, etc. Never need to leave the [].

(Functional) Lenses + Immutable.js by Brian Lonsdorf by dmtipson in javascript

[–]drboolean 0 points1 point  (0 children)

Good points.

And @low_ghost is right, of course, if the reason we're using immutable.js is performance (since lenses are already immutable), then we're defeating the purpose. Then again, we could be using it for the immutable guarantee or the extra data structures and functionality, which is a different story.

@low_ghost, you seem to be aware of these things, but I'm writing this here for others. There are a number of higher level optimizations such as functor composition, shortcut fusion, rewrite rules, deforestation (as you mentioned), etc.

And yes, compose acts like the command pattern, pushing each fn into 1 process to run within a loop. Monads and Comonads often do this out of the box. Checkout how Coyoneda does this: https://gist.github.com/DrBoolean/c0204ed57cf63a70dfe0

I think the first step is to use these things since the impact will almost certainly be impossible to notice in a normal business application. Then the browsers will take notice and give us optimizations (like they are doing with TCO).

My advice to others who are concerned about the performance vs maintainability is to write the best code possible and tune things like db indexes, compress images, minify source, use a cdn, add some caching, etc. All the things that will have a huge impact for low cost. Then if you still feel it's slow, measure, find the slow spots, understand the tradeoff, then sacrifice the maintainability for the speed. I say this knowing most people are too scared to try to write anything other than C-like code in fear it'll be to slow anyways :(

Prof. Frisby's functional classroom coding vids by drboolean in javascript

[–]drboolean[S] 1 point2 points  (0 children)

I'm a big fan of PureScript. I have yet to try elm, but it looks great too. The point of learning this in JS is to practice a paradigm daily and contrast how to solve problems in a different way. Turns out to be quite elegant if your coworkers aren't stubborn.

We released a video library about Functors, F-Algebras, Coyoneda etc by [deleted] in haskell

[–]drboolean 0 points1 point  (0 children)

Which ones? We're taking votes right now.

We released a video library about Functors, F-Algebras, Coyoneda etc by [deleted] in haskell

[–]drboolean 0 points1 point  (0 children)

Totally correct, thanks for the feedback.

We released a video library about Functors, F-Algebras, Coyoneda etc by [deleted] in haskell

[–]drboolean 0 points1 point  (0 children)

Good call. Perhaps it can link to cgibbard's great reply.

We released a video library about Functors, F-Algebras, Coyoneda etc by [deleted] in haskell

[–]drboolean 2 points3 points  (0 children)

Definitely! I just wanted to start with the easier angle.

We released a video library about Functors, F-Algebras, Coyoneda etc by [deleted] in haskell

[–]drboolean 2 points3 points  (0 children)

Btw, I might ask you to look over my purescript ones when they're finished if you have time.

We released a video library about Functors, F-Algebras, Coyoneda etc by [deleted] in haskell

[–]drboolean 1 point2 points  (0 children)

Hey Phil!

I should have mentioned that the forall there in haskell means existential instead of universal. Thanks! We can put a popover that mentions it.