Skip to content

MASantos/FuncBash

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 

Repository files navigation

FuncBash
###

A functional-programming library for bash scripting.
---

Well, this is actually just a very dirty, hack of a proof-of-concept of writing something remotely resembling a bash library 
for functional programming in bash. Just having fun, and seeing how much 
can I stretch this before cheating and looking around at what others have
already done. And there is some things already done, as a quick google search shows.


TODO
---

I just wrote a list wrapper, a map function, a filter function, a foldl, and a list lead and list remain functions.

Todo next could be a foldr and zipWith functions, list comprehension,...


Examples
---

>list {a,A,G,f,H,4,l,M}
a
A
G
f
H
4
l
M


>list {a,A,G,f,H,4,l,M} | map '\cc . tr [[:lower:]] [[:upper:]] <<< $cc '
A
A
G
F
H
4
L
M


>mytoup(){ tr [[:lower:]] [[:upper:]] <<< $@ ;}
>mytoup amdhal
AMDHAL
>list {a,A,G,f,H,4,l,M} | map '\cc . mytoup $cc '
A
A
G
F
H
4
L
M

#map can apply functions to a list that otherwise can't be piped directly to it -contrary to the previous trivial examples.
#For instance
>echo a | printf "thisprint:%s \n"
thisprint:
>list {a..d} | printf "thisprint:%s "
thisprint: bash: echo: write error: Broken pipe
>myprint(){ printf "myprint:%s " <<< $@ ;}
>list {a..d} | map '\c . myprint  $c'
myprint:a
myprint:b
myprint:c
myprint:d

>list {a,A,G,f,H,4,l,M} | filter '\a . grep [[:upper:]] <<< $a '
A
G
H
M


>list {1..30} | map '\x . $(( $x * 3 + 7 ))'
10
13
16
19
22
25
28
31
34
37
40
43
46
49
52
55
58
61
64
67
70
73
76
79
82
85
88
91
94
97

>list {1..30} | filter '\y . [ $(( $y % 3 )) -eq 0 ]'
3
6
9
12
15
18
21
24
27
30

>list {1..30} | filter '\y . [ $(( $y % 3 )) -eq 0 ]' | map '\x . $(( $x * 3 + 7 ))'
16
25
34
43
52
61
70
79
88
97

>list {1..30} | map '\x . $(( $x * 3 + 7 ))' | filter '\y . [ $(( $y % 4 )) -eq 0 ]'
16
28
40
52
64
76
88


*Internally map bash-'evaluates' the lambda expression given. For an aritmetic calculation it knows how to evaluate it by feeding it to an echo function.
However, anything else needs thus to be  a valid bash function that can be evaluated. Ex.: Here we calculate the function f(x)=x^x for the first 30 integers.
>list {1..30} | map '\xx . echo $( echo "e($xx*l($xx))" | bc -lq )'
1.00000000000000000000
3.99999999999999999994
26.99999999999999999957
255.99999999999999999542
3124.99999999999999998813
46655.99999999999999930649
823542.99999999999996914249
16777215.99999999999977231782
387420488.99999999999828982344
9999999999.99999999920085453156
285311670610.99999999390021976186
8916100448255.99999896115162947487
302875106592252.99998626862993420836
11112006825558015.99959787749002176860
437893890380859374.96055953126272707586
18446744073709551613.36477611005321408518
827240261886336764042.91386363202717684205
39346408075296537569954.58504837882476324576
1978419655660313588784638.07494578153416832128
104857599999999999989045366.84551832720883577674
5842587018385982521307755622.23967427261999594087
341427877364219557327724252880.50884843492327778763
20880467999847912031111980274580.43269086838440105377
1333735776850284124226883184879460.74440192525254576703
88817841970012523230518416522959947.88707505132126880958
6156119580207157310681501671928779665.76146596284221780500
443426488243037769879578746371548439823.25119594123263901353
33145523113253374853461832101457693977897.13035500775809187732
2567686153161211134318183201268117865953285.47366537178481729925
205891132094648999980007817024485620316656473.32707809033731206005

>mysum(){ echo $(( $1 + $2 )) ;}
>myconcat(){ echo "$1$2" ;}
>list {1..3} | foldl mysum 0
6
>list {1..5} | foldl mysum 0
15
>list {1..5} | foldl mysum 15
30
>list {a..c} | foldl myconcat ""
abc
>list {a..z} | foldl myconcat "prefix-"
prefix-abcdefghijklmnopqrstuvwxyz

>list {1..20} | lead
1

>list {1..20} | remain
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

BUGS
---

#This is a very dirty hack and thus bugs are lurking in darkness. The broken pipe error points to
#a buggy implementation of list. But this is not the only known bug that's there. See second example. 
>cat ./functionalProgramming.sh| map '\cc . printf "%s" $cc '| head -10
map: DEBUG: func:>printf "%s" $@ <
#!/bin/bash

errmsg(){
[$#-ne2]&&errmsg"errmsg""missingargumentsincalltoerrmsg:$@"
echo"$1:ERROR:$2"
}

list(){#({n..m}|{n1,n2,..nk})->an...am|a1...ak||[a]->[a]
test"$(echo"$*")"=="{}"-o"$(echo"$*")"=="{..}"&&echo""&&return0
#islist=`echo"$*"|grep-E"[0-9]+[[:space:]]+([0-9]+[[:space:]]+)*[0-9]+|[a-zA-Z]+[[:space:]]+([a-zA-Z]+[[:space:]]+)*[a-zA-Z]+"`
bash: echo: write error: Broken pipe

>cat ./functionalProgramming.sh | foldl myconcat "" | head -10
bash: eval: line -54: syntax error near unexpected token `('
bash: eval: line -54: `myconcat  errmsg(){'

About

Proof of concept of writing a (bash) library for functional programming in bash

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages