Skip to content

Instantly share code, notes, and snippets.

@JSuder-xx
JSuder-xx / EffectFn.elm
Created November 15, 2021 15:44
Demonstration of using functions that return commands as a possible replacement for Message(s) and large reducer blocks.
-- Demonstrates
-- * Dispatching a function Model -> (Model, Msg) rather than a message subsequently pattern matching in the reducer.
-- * Benefits include
-- * Module Oriented Programming. Grouping related operations with the type. Improved transparency. Better organization.
-- * Good ergonomics for composing larger states from smaller througn the use of Lenses.
-- * Slightly more succinct.
-- * Drawbacks
-- * The need to aggregate Cmd's (effects) adds a bit of overhead, but then when have effects ever been elegant?
-- * Replay is lost because messages cannot be serialized.
-- * Logic cannot run in a web worker because functions will not serialize across boundary.
@JSuder-xx
JSuder-xx / MsgAsFunction.elm
Last active March 31, 2022 20:49
Unidirectional data flow with Module Oriented programming by using a function a -> a rather than a sum type command.
-- Demonstrates
-- * Dispatching a function Model -> Model rather than a command/message and subsequently pattern matching in the reducer.
-- * Benefits include
-- * Module Oriented Programming. Grouping related operations with the type. Improved transparency. Better organization.
-- * Good ergonomics for composing larger states from smaller througn the use of Lenses.
-- * Slightly more succinct.
-- * Drawbacks
-- * Replay is lost because messages cannot be serialized.
-- * Logic cannot run in a web worker because functions will not serialize across boundary.
--
@JSuder-xx
JSuder-xx / PolymorphicPartialApplication.md
Last active September 7, 2021 12:44
Small study of partial application of polymorphic functions in F#, OCaml, ReScript, PureScript, Haskell, Elm, and TypeScript.

Overview

Curried functions are important for functional programming ergonomics. Polymorphic functions are import for expressiveness, truthfulness, and consequently re-use.

  • Pure functional language such as Haskell, PureScript, and Elm offer all of the benefits.
  • Languages which admit mutation but which honor soundness (F#, OCaml, and ReScript)
    • F# throws a descriptive error message at the location of the offense.
    • ReScript throws a halfway descriptive message but errors the entire module.
    • OCaml monomorphicizes the application based on the first observed subsequent usage.
  • TypeScript, on the other hand, simply allows an unsound typing (which is likely to work out most of the time but will bite you on edge cases).

F#

@JSuder-xx
JSuder-xx / huffman.js
Created July 13, 2021 12:45
Ramdajs Huffman encoding
/**
* By using the RamdaJS library, the entire huffman encoding algorithm is represented with
* - const
* - Function application
* - Function creation (only 4 function closures created, mostly point-free)
* - Constructing and destructuring of both JSON objects and arrays
*
* Thought experiment to verify that a small subset of JavaScript is sufficient to produce sophisticated programs.
* Observe no use of if/switch/ternary/for/while, no dot field access, no infix binary operators.
*/
@JSuder-xx
JSuder-xx / ExpressionTypeClasses.purs
Created June 13, 2021 16:50
Using an expression evaluator as the occasion to experiment with type classes.
module Main where
import Prelude
import Data.Foldable (fold)
import Effect (Effect)
import TryPureScript (h1, p, text, render)
import Control.Apply (lift2)
import Data.HeytingAlgebra (ff, tt)
@JSuder-xx
JSuder-xx / dependency_injection.ts
Created April 18, 2021 16:19
A quick thought experiment on how the article [Dealing with complex dependency injection in F#](https://bartoszsypytkowski.com/dealing-with-complex-dependency-injection-in-f/) might translate to TypeScript.
/**
* Referenced article: [Dealing with complex dependency injection in F#](https://bartoszsypytkowski.com/dealing-with-complex-dependency-injection-in-f/)
*
* Good
* - Placing all services (stateless implementations) in a single object reduces the noise.
* - TypeScript intersection helps with composability (functions can specify exactly what they require).
*
* Not as Good
* - TypeScript inference is a bit weaker than F# so I believe authors must explicitly declare all service
* requirements (i.e. type constraints) rather than having the constraints inferred from the body.
@JSuder-xx
JSuder-xx / safe_strings.ts
Created February 11, 2021 00:51
An example of type system verified strings in TypeScript using template literal strings and tagged types.
/**
* Yet another demonstration of TypeScript awesomeness.
*
* Demonstrates tagged types and template literal strings (v4.1) which allows
* * for the type system to infer the literal string type of value
* * then deconstruct the literal string type into parts
* * in order to parse and validate strings directly in the type system.
*
* See the TRY comments for things to try.
*
@JSuder-xx
JSuder-xx / safe_apis.ts
Last active February 11, 2021 01:04
Example of building safe APIs with type driven development in TypeScript.
/**
* Yet another demonstration of TypeScript awesomeness
* - NonEmptyString demonstrates a simple tagged type (similar to single-case-union in FP).
* - DBConfiguration shows off both union and boolean literal types.
* - EnvironmentDBConfigurationMap finishes with a smart fluent builder utilizing Conditional and Mapped types
* along with type intersection to create a Fluent Builder with stronger verification than is possible
* in C#/Java/C++.
*
* See the TRY comments for things to... well... try.
*
@JSuder-xx
JSuder-xx / micro_decoder.ts
Created February 8, 2021 17:06
A micro JSON decoder API in TypeScript.
/** Micro Api for building decoders. */
module DecoderApi {
type Unknown = unknown;
type ErrorMessage = { kind: "error"; error: string }
export const errorMessage = (error: string): ErrorMessage => ({ kind: "error", error });
export type DecodeResult<value> = value | ErrorMessage
export const isErrorMessage = <value extends unknown>(result: DecodeResult<value>): result is ErrorMessage =>
!!result &&
typeof result === "object" &&
(result as any).kind === "error";
@JSuder-xx
JSuder-xx / typescript_peano_and_list.ts
Created February 7, 2021 16:35
Peano numbers and linked lists verified in the type system (dependent typing) in TypeScript.
/**
* **Power of Infer**
* Infer allows us to match a type for a structure and unpack the internal structure of that type
* into local type variables. This is essentially destructuring/deconstructing/elimination.
*
* The are two fundamental computation operations
* * Building up or constructing types - which can be done with Mapped Types (comprehension).
* * Unpacking types - which can be done with the combination of Conditional Types and the use of infer.
*
* The examples below are the poster-child for this idea of computation through construction/deconstruction