Giter Site home page Giter Site logo

raganwald / raganwald.github.com Goto Github PK

View Code? Open in Web Editor NEW
30.0 5.0 59.0 610.95 MB

raganwald.com jekyll source

Home Page: http://raganwald.github.com

HTML 23.79% Ruby 0.17% CSS 10.42% JavaScript 21.36% Java 6.11% C++ 2.19% XSLT 3.74% Common Lisp 0.71% NewLisp 1.51% Groovy 0.07% CoffeeScript 5.30% Less 11.73% SCSS 12.90%

raganwald.github.com's Issues

unfoldWith via iteration

I really enjoyed Anamorphisms in JavaScript, thanks for taking the time to share your insights. Since we still don't have tail recursion in JavaScript, I wrote this silly iterative unfoldWith - actually, I wrote it because it was fun :). The generator approach was elegant as well, here's my unfoldWith.

const unfoldWith = (fn) => (initialValue) => {
  const accum = [];
  const stack = [initialValue];

  while (stack.length > 0) {
    const value = stack.pop();
    const {result, next, done} = fn(value) || {done: true};

    if (done) {
      continue;
    }

    accum.push(result);
    stack.push(next);
  }

  return accum;
}

Silly example usage:

const rangePositive = (start, end) => unfoldWith((x) => x <= end ? {result: x, next: x + 1} : null)(start);
rangePositive(-2, 2) // [ -2, -1, 0, 1, 2 ]
const rangeNegative = (start, end) => unfoldWith((x) => x >= end ? {result: x, next: x - 1} : null)(start);
rangeNegative(2, -2) // [ 2, 1, 0, -1, -2 ]

http://braythwayt.com/2016/01/03/advice-to-a-beginner.html

Hi Reginald;

Thanks for the excellent article. It brought this picture to mind:

An alternating current, personified as a human moving steadily along some circuit (life's patterns are hard wired after all) flipping between professional and student at each increment.

I think as professionals in an industry that emerged rather than being defined we're still trying to define an objective balance between the two. The lack of definition is responsible for the fogged dialogue that usually accompanies knowledge expeditions. And why the same questions are asked over and over.

My 2cents =)

This issue however is about a small spelling issue:

One of the most important ways to learn something [s/it/is] to experiment

Comments & Questions on "Why Y?"

Hey Reginald!

I've been reading "Why Y? Deriving the Y Combinator in JavaScript" with great pleasure. I was somewhat familiar with the concepts, but following through really helped them click. Thank you!

My process of understanding did involve tinkering with some code, and it seemed to me that the code for the various combinators was at times less simple than it could have been.

For instance, your formulate the why bird as:

const why = fn =>
(
    maker =>
        (...args) => fn(maker(maker), ...args)
)(
    maker =>
        (...args) => fn(maker(maker), ...args)
);

Why not opt for the more intuitive:

const why = fn =>
{
    const wrapper = (...args) => fn(wrapper, ...args);
    return wrapper;
};

I do understand the interest of presenting the first one, it does help with understanding the classical approach based on lambda-calculus which enables recursion without names (the real mind-bender here), but I'd much rather have the second one in my actual code!

In fact, I found it easier to understand the anonymous version by working backward from the version that uses the wrapper binding.

You do say that of a combinator that "It cannot create a named function expression." and "It cannot declare any bindings other than via parameters." But since you relax some other requirements for the idiomatic version, surely those could be relaxed too in practice.

The difference is even more dramatic regarding the long-tailed widowbird/trampoline:

const longtailed =
  fn =>
    (...initialArgs) => {
      let value =
        (x => x(x))(
          maker =>
            (...args) =>
              fn((...argsmm) => new Thunk(() => maker(maker)(...argsmm)), ...args)
        )(...initialArgs);

      while (value instanceof Thunk) {
        value = value.evaluate();
      }

      return value;
    };

My simplified version:

const longtailed = fn => (...args0) =>
{
    const wrapper = (...args) =>
        new Thunk(() => fn(wrapper, ...args));

    let value = fn(wrapper, ...args0);

    while (value instanceof Thunk)
        value = value.evaluate();

    return value;
};

Finally, a question, just to be sure I understood correctly. You write:

Let’s begin our cleanup by moving Thunk inside our function. This has certain technical advantages if we ever create a recursive program that itself returns thunks.

Do you mean that we want to distinguish the thunks returned by a why-form function passed to to the trampoline from the thunk that the trampoline uses internally?

Thanks again, and cheers!

spelling issues: command-pattern.html

I enjoy reading your writing.
Please continue, even if you feel that you keep saying the same things: Repetitio mater studiorum est

Here are a couple of spelling errors.

This appears to work: By prepending the exiting edits onto edits being appended to a buffer, we transform the new edits to producet the same result, synchronizing the buffers.

producet -> produce

And if we put aside the problem of user experience, we have a very string takeaway from dealing with maintaining the future while inserting new edits into the history.

string -> strong ?

Extension methods don't need to be static

It could be done dynamically like:

let String.prototype.reverse = function (...) {...};

'abc'.reverse()
getString().reverse()

In second example JavaScript implementation can't know statically whether getString() will return string, but it will now when it will get to it. This is actually better than :: cause you can polymorph:

let String.prototype.reverse = function (...) {...};
let Array.prototype.reverse = function (...) {...};
// ...
something.reverse()

The key idea is that extension is lexically scoped so that it won't affect any random code. Also, you most surely will want to import/export this extensions so my primitive syntax might not work, but this is only syntax issue.

There are actually a corresponding feature in ruby 2.0 and a perl module for this.

example of function in Trampolines in JavaScript doesn't work

In this example there is a Uncaught ReferenceError: trampoline is not defined

function factorial (n) {
  var _factorial = trampoline( function myself (acc, n) {
    return n
    ? function () { return myself(acc * n, n - 1); }
    : acc
  });

  return _factorial(1, n);
}

factorial(10);
  //=> 362800
factorial(32768);
  //=> Infinity

Lost Symbols

In Functional Mixins in ECMAScript 2015 you go from a simplified approach based on Object.assign, and you end up with a more complex approach based on descriptors.

However, Object.assign by specifications copies enumerable properties values, and also Symbols, while your proposed final code ignores Symbols completely.

Either you didn't want to have Symbols usable for mixins, or you forgot to set them too as descriptors.

Accordingly, your final code needs an utility like the following one, if the purpose was to match the original Object.assign intent plus enumerability:

function assignWithEnumerability(target, source) {
  return Object
    .getOwnPropertyNames(source)
    .concat(
      Object.getOwnPropertySymbols(source)
    )
    .reduce(
      function (target, key) {
        return Object.defineProperty(
          target,
          key,
          {
            enumerable: Object
              .getOwnPropertyDescriptor(
                source,
                key
              ).enumerable
            ,
            value: source[key]
          }
        );
      },
      target
    )
  ;
}

So it can do the meant thing in the right way:

function FunctionalMixin (instanceBehaviour, mixinBehaviour = {}) {
  const typeTag = Symbol("isA");

  function mixin (target) {
    assignWithEnumerability(target, instanceBehaviour);
    target[typeTag] = true;
    return target;
  }
  assignWithEnumerability(mixin, mixinBehaviour);
  mixin[Symbol.instanceOf] = (instance) => !!instance[typeTag];
  return mixin;
}

eventually you can make the suggested utility more suitable for your intents having an extra boolean argument that lets the function consider or not enumerability.

time-space-life-as-we-know-it.html > neighboursOfUrLl

In your article "time-space-life-as-we-know-it", it seems their is a typo:

const neighboursOfUrLl = (square) => [
    square.ul.ur, square.ur.ul, square.ur.ur, square.ur.lr,
    square.lr.ur, square.lr.ul, square.ll.ur, square.ur.lr //repeated declaration
  ];

neighboursOfUrLl(sq).join('')
  //=> "1237BA97"

Should be:

const neighboursOfUrLl = (square) => [
    square.ul.ur, square.ur.ul, square.ur.ur, square.ur.lr,
    square.lr.ur, square.lr.ul, square.ll.ur, square.ul.lr
];

neighboursOfUrLl(sq).join('')
  //=> "1237BA95"

Btw: amazing article, really great job, thanks a lot!

No IPv6 support

The site is missing IPv6 support and thus is inaccessible to people on IPv6-only networks. Furthermore, people on dualstack IPv6-optimized networks will experience slower connections than they would with IPv6 support.

Horizontal iOS

Using this site while holding an iphone horizontally was a brutally poor experience. Something about how the site handles the zoom/viewport made it impossible to get the entire width of the main text column into the view at once so you had to pan side-to-side. Really rough.

give examples on how to replace classes

The article resumes to "classes are wrong because they are difficult to modify". But this issue is also observable in classical programming languages like C where functions call other functions. It will be easier to understand your point of view if you give some examples on how we should replace classes while avoiding "spaghetti code", enabling auto-completion, enabling type checking, ...

Lazy iterables - why not use generators ?

Could you not have used generators in http://raganwald.com/2015/02/17/lazy-iteratables-in-javascript.html ?

As I tried to explain myself the foreign concepts of iterables, in the new ES6 syntax, I wrote this line-by-line explanation of what 'mapIterableWith` was doing.

// mapIterableWith
// Accepts a function to map, and an iterable, and...
// returns an object which...
// under the conventionally defined key, contains a 'generator' function which...
// returns an iterator-looking object whose 'next' method...
// returns an object {done: bool, value: fn(x)} for each value in the passed iterable...
// until the passed iterables' end...
const mapIterableWith = (fn, iterable) =>
  ({
    [Symbol.iterator]: () => {
      const iterator = iterable[Symbol.iterator]();

      return {
        next: () => {
          const {done, value} = iterator.next();

          return ({done, value: done ? undefined : fn(value)});
        }
      }
    }
  });

But I feel like it was really micro-managing what's going on, rather than encapsulating alot of that semantics in a function with a * part of its name where the behavior is more implied.

// mapIterableWith
// Accepts a function to map, and an iterable and ...
// returns a generator which yields values ...
// of the passed function applied to the values of the iterable
const mapIterableWith = (fn, iterable) =>
  ({
    [Symbol.iterator]: function* () {
      const iterator = iterable[Symbol.iterator]();
      yield fn(iterator.next().value);
    }
  });

Am I missing something ?

Example in anamorphisms-in-javascript

function * downToOne(n) {
for (let i = n; i > 0; --i) {
yield i;
}
}

[...downToOne(5)]

//=> [ 1, 2, 3, 4, 5 ]

The array should be [5, 4, 3, 2, 1]

tail call length still hits call stack

Hi,

I was reading http://raganwald.com/2015/02/07/tail-calls-defult-arguments-recycling.html, and it's fascinating stuff, thank you.

However, I was doing some testing myself, and I found that the tail call version of length() still hits Maximum call stack size exceeded at ~ 8,400 item long arrays on my Macbook Pro

Is this because of the inefficiency of [first, ...rest]. My understanding of the article was that the recursion was now ok because JavaScript optimizes away the function call overhead and stack space.

I'm just finding both the tail call length and the inefficient one fall over at the same point:

const length = ([first, ...rest], numberToBeAdded = 0) =>
  first === undefined
    ? numberToBeAdded
    : length(rest, 1 + numberToBeAdded)

OOP, JavaScript, and so-called Classes

This generally looks pretty good. Ihave just a couple thoughts:

Might be worth mentioning that some languages (but not Snmalltalk, Ruby, JS, CL, etc.) treat class as nominal types.

classes: In Smalltalk and Ruby classes aren't just first class "entities" they are first class objects.

prototypes are not classes:

  1. but the "Treaty of Orlando" concluded that they have equivalent power
  2. in self, at least, prototypes are frequently used to build class-like program organization structures. See http://bibliography.selflanguage.org/organizing-programs.html and http://bibliography.selflanguage.org/parents-shared-parts.html . this has also been found to be common in JS

object-orient programming can mean almost anything: I think it does have a single core meaning (at least to classic OOP programmer): structuring programs in terms of the protocols of sets of communicating entities (objects)

the JavaScript approach: I'll argue that ES6 classes are as "first class" as the classes of Smalltalk or Ruby. The fisrt class valued of an ES6 class definition is simply a constructor function so an ES^ "class" is nothing more than a first class function object that follows a particular structural pattern that relates it to a prototype object, its "superclass", and its instances.

Simplify some things with predicate module post

Loved reading your post, though some of the code samples are a little confusing just looking at.

class BankAccount

  def initialize options = {}
    self.extend(
      if options[:frozen]
        Frozen
      else
        Thawed
      end
    )
  end

end

Could be written as

class BankAccount

  def initialize options = {}
    if options[:frozen]
      self.extend(Frozen)
    else
      self.extend(Thawed)
    end
  end

end

Just thought this reads a little nicer. To each his own I guess.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.