diff options
| author | Thomas Voss <mail@thomasvoss.com> | 2023-12-10 02:50:39 +0100 | 
|---|---|---|
| committer | Thomas Voss <mail@thomasvoss.com> | 2023-12-10 02:50:39 +0100 | 
| commit | 9e337a2309c9dcadd91fb3878c2194c477b92bf7 (patch) | |
| tree | 23f5a916acaaa206e3c6b926cceffff51f1bf9a0 | |
| parent | 54219327782db0b5c78aebf2d982f20ea1bef47f (diff) | |
Add another Andy post
| -rw-r--r-- | src/blog/andy-val/angle-bracket.an.gsp | 11 | ||||
| -rw-r--r-- | src/blog/andy-val/cartesian.an.gsp | 4 | ||||
| -rw-r--r-- | src/blog/andy-val/dynamic-func.an.gsp | 4 | ||||
| -rw-r--r-- | src/blog/andy-val/index.gsp | 160 | ||||
| -rw-r--r-- | src/blog/andy-val/naïve.an.gsp | 6 | ||||
| -rw-r--r-- | src/blog/andy-val/posix-fail.sh.gsp | 3 | ||||
| -rw-r--r-- | src/blog/andy-val/smart.an.gsp | 7 | ||||
| -rw-r--r-- | src/blog/andy-val/trap.sh.gsp | 1 | ||||
| -rw-r--r-- | src/blog/index.gsp | 1 | ||||
| -rw-r--r-- | src/style.css | 5 | 
10 files changed, 200 insertions, 2 deletions
| diff --git a/src/blog/andy-val/angle-bracket.an.gsp b/src/blog/andy-val/angle-bracket.an.gsp new file mode 100644 index 0000000..1599dce --- /dev/null +++ b/src/blog/andy-val/angle-bracket.an.gsp @@ -0,0 +1,11 @@ +@span .p {-thomas} @span .pp {-~} @span .p {-〉}@span .cmt {-# `(D…){P…\} is syntax for splitting a process P’s} +@span .p {-thomas} @span .pp {-~} @span .p {-〉}@span .cmt {-# output on the delimiters D.} +@span .p {-thomas} @span .pp {-~} @span .p {-〉}@span .fn {-printf} %s\\n @span .str {-'> '}@span .op {-`}(\\n)@span .op {-{}@span .fn {-grep} MHz /proc/cpuinfo@span .op {-\}} +>cpu MHz		: 1127.333 +>cpu MHz		: 1199.957 +>cpu MHz		: 1139.098 +>cpu MHz		: 1200.000 +>cpu MHz		: 1172.249 +>cpu MHz		: 1199.957 +>cpu MHz		: 1151.501 +>cpu MHz		: 1199.996 diff --git a/src/blog/andy-val/cartesian.an.gsp b/src/blog/andy-val/cartesian.an.gsp new file mode 100644 index 0000000..fb09f2c --- /dev/null +++ b/src/blog/andy-val/cartesian.an.gsp @@ -0,0 +1,4 @@ +@span .cmt {-# foo.c foo.h bar.c bar.h baz.c baz.h} +@span .fn {-echo} (foo bar baz)(.c .h) +@span .cmt {-# Or alternatively:} +@span .fn {-echo} (foo bar baz).(c h) diff --git a/src/blog/andy-val/dynamic-func.an.gsp b/src/blog/andy-val/dynamic-func.an.gsp new file mode 100644 index 0000000..abacc80 --- /dev/null +++ b/src/blog/andy-val/dynamic-func.an.gsp @@ -0,0 +1,4 @@ +@span .p {-thomas} @span .pp {-~} @span .p {-〉}@span .fn {-set} foo bar +@span .p {-thomas} @span .pp {-~} @span .p {-〉}@span .kw {-func} @span .var {-$foo} {\} +@span .p {-thomas} @span .pp {-~} @span .p {-〉}@span .fn {-type} bar +function diff --git a/src/blog/andy-val/index.gsp b/src/blog/andy-val/index.gsp new file mode 100644 index 0000000..63f0699 --- /dev/null +++ b/src/blog/andy-val/index.gsp @@ -0,0 +1,160 @@ +html lang="en" { +	head { m4_include(head.gsp) } +	body { +		header { +			div { +				h1 {-So Much Value} +				m4_include(nav.gsp) +			} + +			figure .quote { +				blockquote { +					p {= +						Complexity is a backdoor and can be misinterpreted as +						sophistication. +					} +				} +				figcaption {-asvln.com} +			} +		} + +		main { +			h2 #value {-Values} +			p {- +				As covered in @a href="/blog/new-sh" {-my last post}, I’m working on +				Andy, my personal shell.  One of the pretty interesting features of Andy +				I think is the way that @em{-values} are handled.  In the conventional +				shell, you can think of a value as a string.  In @code{-echo foo}, both +				‘echo’ and ‘foo’ can be thought of as values.  Values aren’t just +				string-literals though, a Bash process-redirection (@code{-<(cmd)}) is +				also a value; typically one that looks like ‘/dev/fd/N’. +			} + +			p {- +				In Andy this mostly holds, with one very important difference: values +				are not strings — they’re lists of strings.  While the string-literal +				@code{-"foo"} might be a string list of length 1, the +				process-redirection of @code{-<>{cmd\}} is a list of 2 strings — a path +				to a file you can read from, and a path to a file you can write to. +			} + +			p {- +				This is an important distinction to make because of the fact that +				value-concatenation goes from a simple string-concatenation to a +				cartesian product of the left- and right values: +			} + +			figure { +				pre {= m4_fmt_code(cartesian.an.gsp) } +			} + +			p {- +				This is not just constrainted to literals of course, process +				substitutions are also values, so appending each line of a processes +				output with a closing-angle-bracket becomes trivial: +			} + +			figure { +				pre {= m4_fmt_code(angle-bracket.an.gsp) } +			} + +			p {- +				Of course you can also append the closing-angle-bracket using +				@code{-printf} itself, but it’s just an example after all. +			} + +			h2 #dynamic {-Dynamic Code} +			p {- +				What makes Andy different is not just the behavior of values, but where +				you can use them.  In most shells, various syntactic elements are not +				expanded in the same way that regular values are.  The following example +				results in an error because the function name @code{-$foo} doesn’t get +				expanded into @code{-bar}: +			} + +			figure { +				pre {= m4_fmt_code(posix-fail.sh.gsp) } +			} + +			p {- +				Andy doesn’t give a fuck though, it lets you do this if you really want +				to: +			} + +			figure { +				pre {= m4_fmt_code(dynamic-func.an.gsp) } +			} + +			p {- +				Now you might think that this is really retarded — especially if you’re +				a Rust developer — and you know what?  I did too!  But you know what the +				beauty of recreational programming is?  It doesn’t @code{-have} to be +				good — and once you learn to ignore the low-value morons that will +				see you experimenting with new ideas and call it garbage — you can start +				to actually develop some pretty neat solutions to problems. +			} + +			p {- +				For example, Andy like all shells implements support for signal +				handling.  In the POSIX shell this is done via the ‘trap’ builtin +				function: +			} + +			figure { +				pre {= m4_fmt_code(trap.sh.gsp) } +			} + +			p {- +				Now personally, I really don’t like @code{-trap}.  Having to write your +				signal handling code in string is just not very ergonomic.  You +				@em{-can} put your code in a function that you then call in your signal +				handler, but I think Andy can do better.  The way you handle a signal in +				Andy is to simply define a function of the name ‘sigX’ where ‘X’ is the +				name of the signal.  If you want to write a handler for SIGINT, you +				simply define the ‘sigint’ function! +			} + +			p {- +				What if we want to handle multiple signals though?  In the above +				example, we deleted some temporary files on SIGQUIT and also on the +				special SIGEXIT (a fake signal that signifies that the process is +				exiting).  Well the naïve solution is to simply define a handler +				function that you call from your handlers: +			} + +			figure { +				pre .sh {= m4_fmt_code(naïve.an.gsp) } +			} + +			p {- +				But wait… remember how we can dynamically define functions?  What if we +				just… dynamically define our signal handlers: +			} + +			figure { +				pre .sh {= m4_fmt_code(smart.an.gsp) } +			} + +			p {- +				Personally, I think that’s pretty neat, and I like it!  Of course some +				Haskell developer that’s never @em{-actually} written any working +				software will probably be sending me an angry email right about now +				about how this is unsafe code and blah blah, but I don’t care. +			} + +			p {- +				I suppose while this post is primarily about just showing off some of +				Andy’s behavior, I also want to make the point that it’s always a good +				idea to just try new ideas, no matter how contrary they are to ‘best +				practices’ and Rust developers.  Don’t waste your time worrying about +				what other people think about what you make; I used to do that, and it’s +				not great.  Just make shit, even if it’s weird.  You might just +				accidentally add a cool new feature you actually kind of like. +			} +		} + +		hr{} + +		footer { m4_footer } +	} +} diff --git a/src/blog/andy-val/naïve.an.gsp b/src/blog/andy-val/naïve.an.gsp new file mode 100644 index 0000000..661af89 --- /dev/null +++ b/src/blog/andy-val/naïve.an.gsp @@ -0,0 +1,6 @@ +@span .kw {-func} handler { +	@span .fn {-rm} -f (foo bar).tmp +\} + +@span .kw {-func} sigquit { @span .fn {-handler} \} +@span .kw {-func} sigexit { @span .fn {-handler} \} diff --git a/src/blog/andy-val/posix-fail.sh.gsp b/src/blog/andy-val/posix-fail.sh.gsp new file mode 100644 index 0000000..b66ce22 --- /dev/null +++ b/src/blog/andy-val/posix-fail.sh.gsp @@ -0,0 +1,3 @@ +@span .p {-thomas} @span .pp {-~} @span .p {-〉}foo@span .op {-=}bar +@span .p {-thomas} @span .pp {-~} @span .p {-〉}@span .var {-$foo}() { @span .fn {-:}@span .op {-;} \} +bash: `$bar': not a valid identifier diff --git a/src/blog/andy-val/smart.an.gsp b/src/blog/andy-val/smart.an.gsp new file mode 100644 index 0000000..668f189 --- /dev/null +++ b/src/blog/andy-val/smart.an.gsp @@ -0,0 +1,7 @@ +@span .cmt {-# $_ represents the current iteration variable.  You can give an explicit name} +@span .cmt {-# with a for-in loop though.} +@span .kw {-for} quit exit { +	@span .kw {-func} sig$_ { +		@span .fn {-rm} -f (foo bar).tmp +	\} +\} diff --git a/src/blog/andy-val/trap.sh.gsp b/src/blog/andy-val/trap.sh.gsp new file mode 100644 index 0000000..30a60ad --- /dev/null +++ b/src/blog/andy-val/trap.sh.gsp @@ -0,0 +1 @@ +@span .fn {-trap} @span .str {-"rm -f foo.tmp bar.tmp"} QUIT EXIT diff --git a/src/blog/index.gsp b/src/blog/index.gsp index 7ad0296..aac12e0 100644 --- a/src/blog/index.gsp +++ b/src/blog/index.gsp @@ -28,6 +28,7 @@ html lang="en" {  			p {-Posts:}  			ul { +				m4_article(andy-val, {-Values in Andy})  				m4_article(new-sh, {-Making a New Shell})  				m4_article(extend, {-Extensible Scripting})  				m4_article(nvim-ts, {-Hacking with Tree-Sitter on Neovim}) diff --git a/src/style.css b/src/style.css index 6581e9d..42b55e1 100644 --- a/src/style.css +++ b/src/style.css @@ -170,11 +170,12 @@ dl {  /* New classes */  .cmt  { color: var(--lesser); font-style: italic; } +.cnst { color: var(--blue);   }  .fn   { color: var(--accent); }  .kw   { color: var(--green);  } -.str  { color: var(--aqua);   } -.cnst { color: var(--blue);   }  .op   { color: var(--lesser); } +.str  { color: var(--aqua);   } +.var  { color: var(--blue); font-style: italic; }  /* Terminal prompt */  .p  { color: #24DFC4; font-weight: bold; } |