- Optimize
head
.- Fast for all iterables. Still slow for plain dicts.
- Remove
jsonDecode
andjsonEncode
.
Add isScalar
, scalar
, render
.
Better debug printing in show
.
Add isFunSync
, isFunGen
, isFunAsync
, isFunAsyncGen
.
Massive revision:
- Added support for arbitrary iterables such as sets and maps.
- Consolidated lists, dicts, and iterables:
- Most functions that operate on data structures accept any of the above.
- Maps and dicts are considered sequences of their values, not entries.
- Dropped support for additional arguments.
- Use closures instead.
- Renamed various things for brevity and sanity.
- Dropped and added various things, based on usefulness.
Renamed:
isNatPos -> isIntPos
natPos -> intPos
mapFilter -> mapCompact
sortBy -> sort
keyBy -> index
groupBy -> group
sortCompare -> compare
mapVals -> mapDict
rethrow -> panic
assign -> mut
toArr -> arr
Removed:
- global (use built-in `globalThis`)
- isOpt
- isDictOf
- testBy (perf hazard)
- test (perf hazard)
- list (use `arr`)
- comp
- toStr
- reqEach
- reqEachVal
- call
- apply
- cwk
- vacate (see `vac`)
- mapFlat
- mapFlatDeep
- foldRight
- fold1
- findRight
- findIndex
- findIndexRight
- lastIndexOf
- adjoin (use sets)
- toggle (use sets)
- insertAt (use sets)
- replaceAt (use sets)
- removeAt (use sets)
- flat
- flatDeep
- takeWhile
- drop
- dropWhile
- countWhile
- intersect (use sets)
- uniq (use sets)
- uniqBy (use sets)
- min
- max
- minBy
- maxBy
- findMinBy
- findMaxBy
- size (see `len`)
- vals (see `values`)
- hasSize (see `hasLen`)
- eachVal (see `each`)
- foldVals (see `fold`)
- mapValsMut
- mapKeys
- mapValsSort
- findVal (see `find`)
- findKey
- everyVal (see `every`)
- someVal (see `some`)
- invert
- invertBy
- get
- scan
- getIn
- getter
Added:
+ isFinNeg
+ isFinPos
+ isIntNeg
+ isBigInt
+ isJunk
+ isSet
+ isMap
+ isIterAsync
+ isIterator
+ isIteratorAsync
+ isGen
+ isSeq
+ hasMeth
+ isEmpty
+ isVac
+ only
+ arrOf
+ inst
+ jsonDecode
+ jsonEncode
+ npo
+ hasOwnEnum
+ more
+ alloc
+ arrCopy
+ values
+ valuesCopy
+ reify
+ compareFin
+ mapFrom
+ span
+ repeat
+ set
+ setCopy
Instead of creating {}
, always create Object.create(null)
.
When using plain JS objects as dictionaries, they should be null-prototype, to avoid accidentally accessing inherited properties by key. Most of the time this is a non-issue because {}
has only non-enumerable inherited properties. But this could be violated in various edge cases.
Added isListOf
and isDictOf
.
Breaking: renamed each "valid" to "req" (short for "required") for brevity and symmetry with "opt" (short for "optional"):
valid -> req | symmetric with `opt`
validInst -> reqInst | symmetric with `optInst`
validEach -> reqEach |
validEachVal -> reqEachVal |
Added vac
.
Added isCls
, stricter isInst
, extra args in isOpt
.
- Renamed
eachValid
→validEach
(reverted0.9.0
). - Renamed
eachValValid
→validEachVal
(reverted0.9.0
).
More flexible assertions:
valid
now returns the validated value.validInst
now returns the validated value.validEach
now returns the validated value.validEachVal
now returns the validated value.opt(null, test)
now returnsnull
, rather thanundefined
.optInst(null, test)
now returnsnull
, rather thanundefined
.- Removed
only
(now part ofvalid
). - Removed
onlyInst
(now part ofvalidInst
). - All assertion funs now take additional args for the test function.
Slightly stricter isList
, with fewer false positives. For example, it no longer erroneously returns true
for a DOM window
.
times
now calls ƒ(i, ...args)
instead of ƒ(undefined, i, ...args)
. This was always intended, but the error was incorrectly codified in tests.
Type assertions now throw TypeError
instead of Error
.
isInst
error message now includes the name of the failing value's constructor, if possible.
Breaking revision: shorter names, removed a few ƒs, added many more ƒs, stricter validation.
- Renamed:
isBoolean
→isBool
isNumber
→isNum
isFinite
→isFin
isInteger
→isInt
isNatural
→isNat
isInfinity
→isInf
isString
→isStr
isPrimitive
→isPrim
isComplex
→isComp
isFunction
→isFun
isObject
→isObj
isArray
→isArr
isRegExp
→isReg
isSymbol
→isSym
isInstance
→isInst
isIterator
→isIter
isSomething
→isSome
validate
→valid
validateEach
→eachValid
validateInstance
→validInst
onlyStruct
→struct
onlyList
→list
onlyString
→str
onlyDict
→dict
flatMap
→mapFlat
flatMapDeep
→mapFlatDeep
flatten
→flat
flattenDeep
→flatDeep
insertAtIndex
→insertAt
removeAtIndex
→removeAt
intersection
→intersect
pick
→pickKeys
pickBy
→pick
omit
→omitKeys
omitBy
→omit
noop
→nop
values
→vals
toArray
→toArr
bool
→truthy
(the namebool
got reused for an assertion, see below)has
→hasOwn
- Removed:
mask
maskBy
negate
(just usefalsy
)first
(just usehead
)isEmpty
(split intohasLen
andhasSize
)
- Added:
isOpt
isNatPos
True
False
cwk
neg
mapMut
mapValsMut
fold1
replaceAt
takeWhile
dropWhile
count
countWhile
times
sortCompare
(previously private)only
onlyInst
eachValValid
validOpt
prim
num
fin
int
nat
natPos
arr
dict
comp
opt
toStr
len
(split off fromsize
, only for lists)hasLen
(split off fromisEmpty
, only for lists)hasSize
(split off fromisEmpty
, only for structs)zip
- Laxer:
getIn
now treats nil paths as[]
, for consistency with other functions.
- Stricter:
get
,scan
,getIn
,pickKeys
,omitKeys
now validate keys viaisKey
.size
now accepts only dicts. Uselen
for lists.bool
converts nil tofalse
, otherwise asserts that the input is a bool.
- Misc:
call
,apply
,bind
,not
now preservethis
.assign
now returns the target.- Iteration functions access an element by a key only once (relevant for getters and proxies).
isList
now returnsfalse
fornew String
objects and subclasses.isStruct
now returnsfalse
for primitive object wrappers such asnew String
.- Probably a few other tweaks I forgot to mention.
Now only a native JS module. Moved from src/fpx.mjs
to ./fpx.mjs
to make it easier to load directly, such as when using native JS modules in the browser.
- Additional arguments now use native rest and spread instead of hardcoding
a, b, c, d, e
. In modern engines, this should perform similarly in most scenarios. take
anddrop
now allowInfinity
as count.testBy
andtest
now compareDate
instances by.valueOf
.range
now requires start and end to be integers.pickKeys
allows nil in place of key list (equivalent to[]
).show
now catchesJSON.stringify
exceptions, falling back on default stringification.call
,apply
,bind
now use native spread, and no longer setthis
to the function itself.
Renamed the source file from fpx.js
to fpx.mjs
to support some obscure uses.
Insignificant micro-improvements.
New functions:
everyVal
: same asevery
but for struct valuessomeVal
: same assome
but for struct values
New term: non-list objects are now called "structs". All object-related functions in Fpx validate their inputs via onlyStruct
.
New functions:
isStruct
onlyStruct
entries
Breaking: keys
and values
are stricter; they're now consistent with all other object-related functions.
keys
now accepts onlynull
,undefined
, and non-list objects, rejecting other inputs with an exceptionvalues
now accepts onlynull
,undefined
, and non-list objects, rejecting other inputs with an exception
Breaking: cast functions now serve as nil-tolerant assertions.
onlyString
now accepts onlynull
,undefined
, and strings, rejecting other inputs with an exceptiononlyList
now accepts onlynull
,undefined
, and lists, rejecting other inputs with an exceptiononlyDict
now accepts onlynull
,undefined
, and dicts, rejecting other inputs with an exception
Breaking testBy
changes:
- function pattern: always convert result to boolean
- regexp pattern: apply only to string input; no implicit conversion
- object pattern: apply only to non-list object; ignore list and function inputs
Breaking maskBy
changes:
- regexp pattern: use
onlyString
to validate input - regexp pattern: use
String.prototype.match
instead ofRegExp.prototype.test
- list pattern: use
onlyList
to validate input - object pattern: use
onlyStruct
to validate input
Breaking: take
and drop
now accept only natural numbers as the second argument, rejecting negative integers and other inputs.
Breaking change: strictness.
-
List functions accept
null
,undefined
, and lists, rejecting other arguments with an exception. This includes list-specific getters such ashead
andtail
. -
Dict functions accept
null
,undefined
, and non-list objects, rejecting other arguments with an exception.
This change does not affect generic getters such as get
and size
.
show
now adds quotes around a string.
Massive rework that makes Fpx a realistic replacement for Lodash. Breaking.
- removed 22 functions and 1 alias
- added 51 functions
- renamed 3 functions
- greatly improved performance
- size went from 9 KiB to 12 KiB
Removed most weyrd-ass function transforms like and
, or
, juxt
, alter
, etc. Years of practice have revealed major drawbacks and questionable value. The best way to compose functions is to write functions that call functions. It's that simple.
Added tons of new list and dict functions. See the documentation.
All "iteration" functions now accept additional arguments for the operator.
Breaking changes in existing functions:
flat
→flattenDeep
foldl
→fold
foldr
→foldRight
- removed the
isPlainObject
alias forisDict
keys
andvalues
now only work on dicts- removed handling of
this
; just pass it as an additional operator argument
Approximate diff of the exports:
-alter
-and
+assign
-comp
-compAnd
+compact
-cond
+each
+eachVal
+findIndex
+findIndexRight
+findKey
+findMaxBy
+findMinBy
+findRight
+findVal
-flat
-foldl
-foldr
+flatMap
+flatMapDeep
+flatten
+flattenDeep
+fold
+foldRight
+foldVals
-getAt
+getter
+global
+groupBy
-ifelse
-ifexists
-ifonly
-ifthen
+intersection
+invert
+invertBy
+isEmpty
+isKey
-isPlainObject
+isSomething
-juxt
+keyBy
-list
+lastIndexOf
+mapFilter
+mapValsSort
+max
+maxBy
+min
+minBy
-or
-pipe
-pipeAnd
+omitBy
+omitKeys
+onlyDict
+onlyList
+onlyString
+partition
+pickBy
+pickKeys
+range
+reject
-rest
-seq
-spread
+sort
+sortBy
+sum
+sumBy
-testAnd
-testArgsAnd
-testArgsOr
-testOr
+toArray
+uniq
+uniqBy
+vacate
+validateInstance
Added isIterator
, published show
.
Added lt
, gt
, lte
, gte
.
- added
isInfinity
isList
is fasterisInteger
is faster
0.4.0
has massive breaking changes. It removes a few functions and changes the argument order in 15 functions. It should basically be treated as a different library under the same name. Migrating an existing application is likely to cause subtle breakage, and existing dependents should probably remain on 0.3.1
.
Functions added:
insertAtIndex
Functions removed:
applyBind
- tends to be unused, side effect of how
bind
was defined
- tends to be unused, side effect of how
curry1
- leads to shorter but harder to understand code, not worth the tradeoff
flip
- hazardous due to JS's unpredictable argument count
revise
- leads to code that is both extremely short and extremely hard to understand; not worth the tradeoff
fanout
funnel
- not any better than regular imperative code with variable reassignment
Functions changed:
testBy
: changed arguments to(operand, pattern)
foldl
: changed arguments to(list, init, fun)
foldr
: changed arguments to(list, init, fun)
map
: changed arguments to(list, fun)
filter
: changed arguments to(list, fun)
find
: changed arguments to(list, fun)
every
: changed arguments to(list, fun)
some
: changed arguments to(list, fun)
procure
: changed arguments to(list, fun)
take
: changed arguments to(list, count)
drop
: changed arguments to(list, count)
mapVals
- changed arguments to
(dict, fun)
- removed
mapDict
alias; usemapVals
instead
- changed arguments to
mapKeys
- changed arguments to
(dict, fun)
- changed arguments in mapping function to
(key, value)
- changed arguments to
maskBy
- changed arguments to
(operand, pattern)
- changed arguments to
validate
- changed arguments to
(operand, validator)
- changed arguments to
Rule/mnemonic for argument order: primary operand first. Motivation:
- operator-last is more syntactically convenient when the operator is an inline function, especially if multiline
- consistent operand-first is easier to remember
- the original motivation for operator-first, currying, tends to be inconvenient and/or hazardous in JS
In list functions, the argument order is now similar to Array.prototype
built-ins.
Removed the preservation of this
from all higher-order functions that create a new function: bind
, and
, or
, not
, ifelse
, ifthen
, ifonly
, ifexists
, cond
, pipe
, comp
, seq
, pipeAnd
, juxt
, rest
. Motivation: too implicit to rely on, tends to be unused, no tests.