Loglo:一个非常实验性的编程环境,由Avi Bryant设计

2020-06-18 02:17:50

头顶上的LOGO用两条轨迹标出了CSV-5,它是由无数个细胞组成的电灯主体,每个细胞都是由想象者在曼哈顿设计的,他们为了设计一个单一的标志而赚的钱,比递送者一生的收入还要多。尽管它们努力脱颖而出,但它们都在一起涂抹,特别是以每小时120公里的速度行驶。

-尼尔·斯蒂芬森(Neal Stephenson),Snow Crash。

Loglo是Glowforge的标识:由Avi Bryant设计的一个试验性的非常试验性的编程环境。它目前专注于生产SVG输出的狭窄领域,以馈送到数控机床或激光切割机。

如果你迫不及待地想试一下,你可以在这里试一试,希望在读完这篇文档的其余部分之后再试一试。请注意,您无法保存、加载、导出、导入、保存、共享或真正从您的工作中获得任何价值,并且只提供了标准库的最基本信息。但可能有足够的工作让你对它有个了解。如果您确实尝试过,请通过[email protected]将反馈发送给我。

也没有参考文档,如果有,它将立即过时。但是如果你幸运的话,我下面描述的大部分仍然是正确的。来吧,我带你四处转转。

所以。乍一看,Loglo只是一个非常简单的电子表格,看起来很可疑,它可能是由一个没有设计技能、只对前端工程有模糊理解的开发人员制作的。但是:有单元格,你可以点击一个,在公式栏中键入一个数字,然后按Enter键,它就会出现在单元格中。

你也可以做算术,但只有在你知道RPN的情况下。(如果你不这样做,那就太令人兴奋了:你今天就能学到一些新东西。但不幸的是不是在这里。我建议先阅读一篇关于基于堆栈的编程的文章。)。

再说一遍,我们来这里是要做什么?哦,对了,画点东西吧。Loglo很周到地提供了恰好一个绘制基元,该基元生成一条1像素长的单行。如果你眯着眼睛,你可以看到它在细胞内渲染。

单像素线可能有一点限制。我们可以用另一个原语来扩大它。现在就接受感叹号吧,我稍后会解释的。

由于这是一个电子表格,我们可以引用其他单元格(不区分大小写,谢天谢地),这可能不会让您感到惊讶。

我们可以将A1 Scale!";行保留在A2中,而将";A1 Scale!";移到下一个单元格中,而不是一次写入所有第#34;行A1 Scale!";。Loglo从左到右评估行,并维护一行中的单个堆栈。因此,将小程序拆分到更多的单元格不会影响语义,只会让您更多地展示您的工作。

当我们在做电子表格技巧时,这里还有另一个:A1是绝对引用,但这里是相对引用,它向上指向B1中的70&34;行。

使用^#34;^&34;可以实现这种很好的模式,您可以将每个转换的参数化提取到一个在结果上方可见且易于编辑的单元格中。

要构建形状,我们需要将线段连接起来。";JOIN!";将把一行的开头连接到另一行的结尾。

最后,我们可以闭合循环并使用";Fill!";将路径转换为形状。

我们做了一个三角形!这似乎值得给它起个名字。冒号引入一个符号;";.";类似于PostScript';s&34;def";,并在全局词典中创建一个新条目。在单元格中,我们只显示新标签。

在这里,我们将小程序片段放在大括号中,使其成为代码块,该代码块被视为一个值,而不是立即执行。然后,我们将其命名为Spin&34;,就像我们之前命名的三角形一样。

但是,如果我们将显式的";180旋转!";替换为";Spin&34;,单元格将显示";{}";。这意味着堆栈的顶部是代码块对象。

如果我们希望实际执行该代码块,则必须使用运算符";!";。这就是为什么我们一直看到缩放、旋转等等:这些词只是引用内置代码块,我们需要显式地评估它们。(另一方面,像";和!#34;这样的运算符本身是自动求值的;要延迟它们,您需要将它们括在{}中)。

稍后,还会有其他求值运算符,最重要的是用于映射(";@";?)。和减少(";%";?)。过多的清单。

稍微改变一下方式:在电子表格网格下面,Loglo有一个检查器,您可以在其中尝试表达式并查看比单元格内更详细的结果。在这里,我们将三角形和它的旋转兄弟组合在一起,这样我们就可以同时看到它们。你可能会对他们的相对位置感到惊讶。为什么三角形会绕着右上角旋转呢?

如果我们只检查原始三角形,并将光标移到它上面,我们会看到标记为0到2的3个顶点。标记第0个顶点的圆圈较大,表明它是锚点。任何变换都会将该点视为原点。

锚点不一定是其中一个顶点。一旦标准库稍微充实了一些,您就可以将任何其他形状的顶点、中心点,或者只是某个地方的任意点设置为锚点。

使用顶点索引可能很方便,但有时您需要更稳定的标识符。";tag!";将获取一个符号并用它标记当前锚点;然后您可以使用该符号(例如)将锚点设置到该点。

他们还能在更复杂的操作中坚持下去。正如您在这里看到的,当我们将这两个形状组合在一起时,顶点被重新编号为它们在组内的全局索引…。

让我们通过稍微重置一下网格并创建一个面向侧面的三角形来完成这件事。紧接着,我们将给它起一个富有想象力的名字";triangle2。";

分组后,您可以看到该三角形和triangle2重叠。这绝对不是故意这样做的,只是为了让我炫耀一下布尔运算。

最后,为了提醒自己这是一个电子表格,我们将把原来的30度旋转改为50度旋转,敬畏地看着其他一切都在实时更新。

反应式界面(如电子表格)确实需要不可变的、组合的API,而不是命令式的API。当副作用被不断地重新评估时,它们会变得太混乱和令人困惑。所以经典的徽标,或者它的任何后代,比如Canvas API,在这里真的是行不通的。

我见过其他构图图形API(大喊涂鸦),但总是假设您是从形状或图像作为基元开始的,而不是线条。路径上的加入操作对我来说是一个重大突破。

徽标从来没有曲线,贝塞尔控制点太糟糕了,无法通过编程直接使用。我已经实现了一个样条运算,它可以将直边形状转换成漂亮的曲线,包括最令人满意的将正方形转换成真正非常接近圆形的东西,但是我还没有写好所有的代码来正确地对这些曲线进行布尔运算,所以我还没有准备好展示它。(我使用的方法是基于这篇文章)。

我最初以为我会使用笔记本用户界面--具体地说,是可观察的,这是反应性和奇妙的。但电子表格的问题在于,它们非常紧凑。单个笔记本单元格的空间中可以有100个电子表格单元格。那看起来应该值很多钱。

电子表格还允许更流畅、更独特的空间组织,就像MacOS上的旧空间查找器一样。(嗨,奥马尔!)。

但出于同样的原因,电子表格需要紧凑的程序表示,并鼓励将您的程序拆分成非常小的片段。我见过的最紧凑的语言是堆栈语言,无论是就标记的数量而言,还是因为它们没有嵌套使它们更具一维性,也就是说,它们不会在任何地方都使用换行符。这非常适合电子表格的传统(我认为是有用的)单行输入。

此外,堆栈语言中激进的语法缺失让人联想到最初的徽标,我怀疑这对新手用户来说是一件好事。(尽管我可能会用所有的类K运算符来破坏这一点,我可能应该重新考虑一下。)。

让电子表格的整行保持相同的堆栈是一个在游戏中相对较晚出现的想法。我最初抵制它,因为它增加了一个固定的评估顺序,这似乎与电子表格非常相反。但在实践中,我认为人们不管怎样都是从左到右工作的,隐含地提到左边的邻居感觉很好(而且很紧凑!)。另外:我喜欢您可以在单个单元格内从左到右编写相同的程序,或者使用相同的单词,可以随心所欲地拆分成块,从左到右横跨一行,并且语义是相同的)。

如果您不使用^34;^;运算符,则相同。那个可能是个错误。

还有严格的从上到下的评估(这样操作符就可以工作了(那个操作符可能真的是个错误))。这比从左到右更有问题,但到目前为止,我说服自己,因为你可以用{}推迟评估,所以你可以通过这种方式获得推荐人,所以这是可以的。

在编写本文档的过程中,我意识到对于基于行的求值,我们确实应该切换行/列表示法,并为行指定字母,这样A1、A2、A3都可以按顺序求值。但是我不想重做所有的截图,所以我以后会重做的。

堆栈语言适用于电子表格,但电子表格也适用于堆栈语言。只要引入一个单元格分隔符,就可以在堆栈的任何位置窥视,这对于可见性来说是非常棒的。它还(隐式地,不需要任何额外类型)为您可以引用的中间结果提供一个名称,这使得您对DUP/SWAP游戏的需求大大减少。(对于您提取的函数,您仍然需要它们,但在直接用户代码中就不那么需要了。)