 # e.g. if you want to put function calls on the same line to save space, and get better readability :)
 doit = (xs..., x) -> x
 
+# flytta till ramda-extras, typ 'composeP2'
+_composeP2 = (f, g) -> ->	
+	context = @
+	value = g.apply @, arguments
+	if isThenable value
+		if f._fail then value.fail (x) -> func.call context, x
+		else res.then (x) -> func.call context, x
+	else f.call @, value
+
+# _composeP = (f, g) ->
+# 	->
+# 		context = @
+# 		value = f.apply @, arguments
+# 		if isThenable value
+# 			if f._fail then value.fail
+
+# :: like http://ramdajs.com/docs/#composeP but lets you go into the fail-branch of the promise as well
+composeP2 = (fs..., f) -> reduceRight _composeP2, f, fs
+
+# :: f -> f   # assoces a _fail flag on a function f so that composeP2 knows you'll want to go into the fail branch
+fail = (f) -> assoc_ '_fail', true, f
+
+
+# ----------------------------------------------------------------------------------------------------------
+# OBJECT
+# ----------------------------------------------------------------------------------------------------------
 isEmptyObj = eqDeep {}
 
-# like http://ramdajs.com/docs/#pickAll but instead of undefined it returns the value of the key in the firs object
+# like http://ramdajs.com/docs/#pickAll but instead of undefined it returns the value of the key in the first argument
 pickOr = (keysAndDefaults, o) ->
 	picked = pickAll keys(keysAndDefaults), o
 	valueOrDefault = (v, k) -> if v == undefined then prop(k, keysAndDefaults) else v
 	return mapObjIndexed valueOrDefault, picked
 
+# :: o0, o1, o2, ... -> o   # merges many objects into original
+mergeMany = (original, objects...) -> reduce merge, original, objects
+
+# :: a, [s], o -> a   # if the path exist in object, return it's value, otherwise defaultValue
+pathOr = curry (defaultValue, path, o) -> R.or(getPath(path, o), defaultValue)
+
+# stolen from https://github.com/ramda/ramda/blob/master/src/internal/_isThenable.js
+isThenable = (value) -> value != null and value == Object(value) and typeof value.then == 'function'
+
+# :: {k:v} -> {k:v}   # makes a shallow copy of o
+### jshint -W027 ###
+cloneShallow = (o) ->
+	switch
+		when isa(String, o) then return o
+		when isa(Number, o) then return o
+		when isa(Date, o) then return new Date(o)
+		when isa(RegExp, o) then throw new Error('TODO: cloneShallow of RegExp not yet implmented')
+		when isa(Object, o)
+			ret = {}
+			for k in o
+				ret[k] = o[k]
+			return ret
+		else throw new Error("TODO: cloneShallow of #{type(o)} not yet implemented")
+
+# :: f -> o0 -> o1 -> o   # like https://clojuredocs.org/clojure.core/reduce-kv
+reduceObj = curry (f, init, o) ->
+	ret = cloneShallow init
+	callF = (v, k) -> ret = f(ret, k, v)
+	mapObjIndexed callF, o
+	return ret
+
+
+# ----------------------------------------------------------------------------------------------------------
+# UI-HELPERS
+# ----------------------------------------------------------------------------------------------------------
 # takes a function f and it's params and return a function y which can later be invoked as a callback
 callback = (f, params...) -> () -> f(params...)
 

R = require 'ramda'
lo = require 'lodash'
{curry, concat, I, compose, composeP, reduce, mapObjIndexed, chain, length, filter, slice, eqDeep, prop, get, has, keys, pickAll, merge, assoc, all, path, functions} = R #auto_require:funp

# is is a keyword in coffee, so we indroduce isa as an alias instead
isa = R.is

dropLast = curry (n, xs) -> slice 0, xs.length - n, xs

# path is such a good name, therefor here's an alias
getPath = R.path

# compose and call - makes syntactic sugar so we don't have to use so many parans
cc = (functions..., data) -> compose(functions...)(data)


# calls f with all arguments that has been passed
indirect = (f) -> (params...) -> (secondaryParams...) -> f(params..., secondaryParams...)


# ----------------------------------------------------------------------------------------------------------
# STRING
# ----------------------------------------------------------------------------------------------------------
capitalize = lo.capitalize
toStr = (a) -> a+''

# ----------------------------------------------------------------------------------------------------------
# MATH
# ----------------------------------------------------------------------------------------------------------
clamp = curry (a, b, x) -> Math.min b, Math.max(a, x)



# ----------------------------------------------------------------------------------------------------------
# UNPURE STUFF
# ----------------------------------------------------------------------------------------------------------
# unpure assoc (ie. good if you want to assoc something to a function)
assoc_ = curry (k, v, x) ->
	y = x
