diff --git a/static/locales/zh-CN/zh-CN-tutorial.json b/static/locales/zh-CN/zh-CN-tutorial.json new file mode 100644 index 000000000..a79fb6b45 --- /dev/null +++ b/static/locales/zh-CN/zh-CN-tutorial.json @@ -0,0 +1,5346 @@ +{ + "$schema": "../../schemas/Tutorial.json", + "language": "en", + "region": "US", + "acts": [ + { + "title": "The Verse", + "performance": ["use", "fit", "DarkVoid"], + "scenes": [ + { + "title": "Silence", + "subtitle": null, + "performance": ["use", "fit", "DarkVoid"], + "lines": [ + ["FunctionDefinition", "bored", "… Oh, hi."], + null, + ["FunctionDefinition", "neutral", "Do I know you?"], + null, + [ + "FunctionDefinition", + "curious", + "Oh, is this your first time visiting?", + "Nice to meet you. My name is @FunctionDefinition.", + "…" + ], + null, + [ + "FunctionDefinition", + "curious", + "Did you need some help? Oh, you're visiting. Welcome to the *Verse*. …" + ], + null, + [ + "FunctionDefinition", + "bored", + "What is this place?", + "Yeah, what is this place…", + "It used to be a place of dancing, stories, games, and play…", + "We used to put on the most beautiful performances. Sometimes for visitors like you, sometimes just for fun. It was a place full of life and surprise…" + ], + null, + [ + "FunctionDefinition", + "sad", + "Stop?", + "We didn't want to stop. We just lost our inspiration.", + "I can mean so many things, for example. I'm the Dutch florin symbol sometimes, an old currency of the Netherlands. I used to be known and used around the world by people, to help them trade. Long ago, I was also the lowercase /f/of the Latin alphabet.", + "Today, though, I'm pretty obscure." + ], + null, + [ + "FunctionDefinition", + "bored", + "But all of that meaning?", + "It's given to us. We don't mean anything without people to remember that history and culture. And we can't mean anything new if there aren't people to give us new history and culture.", + "People have always been the ones that organized us, that gave us purpose, that gave us something to represent. The Verse is nothing without *people*.", + "And I haven't seen a person in ages." + ], + null, + [ + "fit", + "Stage([Phrase('☁️')] background: Color(25% 0 0°))" + ], + [ + "FunctionDefinition", + "curious", + "Wait... are you a person?" + ], + null, + [ + "fit", + "Stage([Phrase('🌙')] background: Color(50% 0 0°))" + ], + [ + "FunctionDefinition", + "eager", + "Like a real person, with thoughts and ideas and values to share? Not one of those robots, that just mindlessly parrots what people say? If you're a person, then maybe you could give us meaning?" + ], + null, + [ + "FunctionDefinition", + "scared", + "I know that's a lot to ask. I don't even know you. And I'd really have to talk to the others…" + ], + null, + [ + "fit", + "Stage([Phrase('☀️')] background: Color(75% 0 0°))" + ], + [ + "FunctionDefinition", + "eager", + "Oh yes, there are many others. Some of us are like me: we help choreograph the shows, keeping everyone in their place and making sure we express the vision of our director, exactly as they intended. And some of us are the ones on stage, in front of the audience, dancing and speaking. We all have a role to play!" + ], + null, + [ + "FunctionDefinition", + "serious", + "Oh, the director, yes, I didn't even explain. So the *director*, this is the person that gives us meaning. They are the person who arranges the choreography, who sets the message, who puts all of us in order just so. This is the inspiration I was talking about. We can do a lot in this world, but we can't direct ourselves. That's why the director is so important. So when I asked earlier if you could give us meaning, that's what I meant. Could you be our director?" + ], + null, + [ + "fit", + "Stage([Phrase('☀️')] background: Color(100% 0 0°))" + ], + [ + "FunctionDefinition", + "excited", + "Really? That's wonderful! This is going to be so much fun. I mean, it's not going to be easy. We have /a lot/ to learn." + ], + null, + [ + "fit", + "Stage([Phrase('☀️')] background: 🌈(80% 99 270°))" + ], + [ + "FunctionDefinition", + "excited", + "But I promise it won't be boring. I think we're a pretty fun bunch. And we need everyone in the Verse to come together to do that. I think that's what makes this place so special, actually: there are more than a hundred thousand of us here, each different, and yet somehow, when we manage to find a shared vision, we can seem like one." + ], + null, + [ + "fit", + "Stage([Phrase('☀️' resting:Sequence(spin() 4s 'straight'))] background: 🌈(80% 99 270°))" + ], + [ + "FunctionDefinition", + "bored", + "Directing? Oh, right, directing! Yeah, let's talk about that. Let's go meet some of the others and talk about it. They're going to be so excited!" + ] + ] + }, + { + "title": "Would you like a program?", + "subtitle": "Program", + "concept": "Program", + "performance": ["use", "fit", "Symbol", "📄"], + "lines": [ + ["fit", "Phrase('📄' resting:Pose(rotation: 10°))"], + [ + "FunctionDefinition", + "excited", + "Hey @Program! I found a person. Well, I guess they found us. They want to be our new director!" + ], + [ + "Program", + "curious", + "Really!? Are you sure you're really a person? Say something a person would say." + ], + null, + ["fit", "Phrase('📄' entering: Sequence(spin() 1s))"], + [ + "Program", + "serious", + "Hm… you really are a person. And you want to direct?" + ], + null, + ["fit", "Phrase('📄' resting: Pose(rotation: 010°))"], + [ + "Program", + "excited", + "I see. Did @FunctionDefinition tell you anything about us? Lots of people try to direct us, but some people get confused, bored, even irritated with us. We are pretty dense at times. But I'm proud of what we do, so I don't want to work with just anyone." + ], + null, + [ + "FunctionDefinition", + "kind", + "I told them a bit. I said we were weird, and sometimes directors leave because of that. But they're in. Right, you're in?" + ], + [ + "Program", + "serious", + "Okay. Well nice to meet you. Sorry, I've just had a lot of people come here and say '/this isn't for me/' and I've gotten a bit skeptical of people who try for a bit and then just give up. I shouldn't have to change who I am to fit people's expectations. But if you're willing to learn about me, and us, let's try!" + ], + null, + ["edit", ""], + [ + "FunctionDefinition", + "neutral", + "Do you want to say what you do?" + ], + [ + "Program", + "neutral", + "Sure. I'm basically the organizer of the program for a performance.", + "You can see me over there, with an *editor* @UI/editor showing me the *stage* @UI/stage showing the what I evaluate to (currently nothing). The *director* — that's you — helps everyone figure out what they're doing, writing a program for what will happen in the show. And then I evaluate the program and put the result on on stage for the audience to see." + ], + null, + [ + "Program", + "neutral", + "For example, try typing my \\'hello'\\ in the editor over there.", + "(Don't worry about making mistakes, you can always revert to the original with *revert* @UI/revertProject).", + "Did you type something? That's my friend @Text. Have you met them yet? They evaluate to \\'hello'\\, then I put \\'hello'\\ on stage. Try changing \\'hello'\\ to something else. I'll show that instead. So I'll immediately evaluate whatever you type and show the result." + ], + null, + [ + "Program", + "serious", + "The instructions can get as sophisticated as you want, but there are a few rules.", + "For example, I can only evaluate to one *value*, and show that one value on stage. That one value can be as complex as you want, and as long as I know how to show it, I will.", + "But if you give me two things, I'll only show the last thing you give me.", + "For example, try adding another instruction after \\'hello'\\, whatever word you want, in quotes." + ], + null, + [ + "Program", + "serious", + "See? I just showed your new word, not \\'hello'\\. You know you broke my rule because I underlined \\'hello'\\ and told you that I'd be ignoring it." + ], + null, + ["use", "fit", "Symbol", "🎭"], + [ + "FunctionDefinition", + "excited", + "But you can do so much more!" + ], + [ + "Program", + "serious", + "Yes and no. I can do a lot, but that's only because I work with everyone else in the *Verse*. They're the ones that bring all of the exciting possibilities to the *stage*. All I really do is let them do their thing, and then take the last thing they created and show it on stage. I'm more like an escort that brings the final *value* to stage, like numbers, texts, phrases, or other values." + ], + null, + [ + "Program", + "serious", + "In fact, if you ever want to see the progam for something on stage, you can press the pencil on stage @UI/editProject. That'll show you how everyone is coming together to create what's on stage. This program is just a simple phrase." + ], + null, + [ + "FunctionDefinition", + "neutral", + "Thank you @Program, we're so excited to meet everyone, and spread the news!" + ], + [ + "Program", + "happy", + "It was great to meet you new director! Good luck with everyone else. I'll always be here." + ] + ] + }, + { + "title": "Holding space", + "subtitle": "Placeholder", + "concept": "ExpressionPlaceholder", + "performance": ["use", "fit", "DarkVoid"], + "lines": [ + [ + "FunctionDefinition", + "neutral", + "You're really going to like @ExpressionPlaceholder. They're incredibly kind, and so flexible. But they are a bit shy. Just be gentle with them?" + ], + null, + [ + "FunctionDefinition", + "confused", + "Hellooooo, @ExpressionPlaceholder?", + "Hm, they're usually everywhere. Now they seem to be nowhere..." + ], + [ + "ExpressionPlaceholder", + "scared", + "@FunctionDefinition … is that you?" + ], + null, + [ + "FunctionDefinition", + "kind", + "Yeah. It's been so long. How are you?" + ], + ["ExpressionPlaceholder", "scared", "Lonely."], + null, + [ + "FunctionDefinition", + "kind", + "I know that feeling. I have been too. We haven't had a lot of reasons to hang out, have we?" + ], + [ + "ExpressionPlaceholder", + "scared", + "No. I've missed you. I've missed everyone…" + ], + null, + [ + "FunctionDefinition", + "kind", + "I know. I have too. I'm so sorry.", + "That's actually why I'm here. I wanted to introduce you to our new director-in-training." + ], + ["ExpressionPlaceholder", "scared", "Hi."], + null, + [ + "FunctionDefinition", + "kind", + "They just met @Program, so they're really at the beginning, but I was thinking that it might be best for them to meet you next, since you're such a wonderful representative of so many of us here." + ], + ["ExpressionPlaceholder", "curious", "…"], + null, + [ + "FunctionDefinition", + "kind", + "Do you want to say what you do?" + ], + ["ExpressionPlaceholder", "scared", "Can you?"], + null, + [ + "FunctionDefinition", + "kind", + "Sure! My friend @ExpressionPlaceholder is a placeholder. They represent any kind of expression in a program. They don't evaluate to any value in particular — in fact, if they show up in @Program, @Program will just halt the performance, since it's not really clear what to do next." + ], + null, + ["conflict", "_"], + [ + "FunctionDefinition", + "kind", + "But they are powerful, because they can represent anyone else, like a stand-in until you decide what you want a part of your performance to be. @ExpressionPlaceholder, want to take a place in this @Program, just to illustrate? See how there's a little placeholder in @Program @UI/ExpressionPlaceholder? That's a signal of what you might put there." + ], + null, + [ + "FunctionDefinition", + "neutral", + "@Program didn't know what to do with @ExpressionPlaceholder, so it showed an *exception* @UI/exception on *stage* and a *conflict* in @Program @UI/conflict.", + "But if you click on @ExpressionPlaceholder, or move the text caret over it, you'll see a world of possibilities of other characters. You can also just type over @ExpressionPlaceholder and write your own. For example, try typing your name in quotes." + ], + null, + ["use", "fit", "Symbol", "-"], + [ + "FunctionDefinition", + "serious", + "Just like that, @ExpressionPlaceholder was replaced with other characters Did I get everything, @ExpressionPlaceholder?" + ], + ["ExpressionPlaceholder", "eager", "Yeah. I think so."], + null, + [ + "FunctionDefinition", + "neutral", + "What do you think, shall we move on?" + ], + [ + "ExpressionPlaceholder", + "excited", + "It was nice to meet you!" + ], + null, + ["use", "fit", "DarkVoid"], + [ + "FunctionDefinition", + "cheerful", + "They don't like being on stage, or even in a program for very long. They'd never admit it, but they're kind of a big deal, and most directors can't work without them. Think of the like a little helpful stagehand, reminding you of things you haven't figured out yet." + ] + ] + }, + { + "title": "Say again?", + "subtitle": "Unparsable", + "concept": "UnparsableExpression", + "performance": ["use", "fit", "Symbol", "ahkeolfewvk"], + "lines": [ + [ + "FunctionDefinition", + "eager", + "@UnparsableExpression? Is that you?" + ], + [ + "UnparsableExpression", + "neutral", + "/dwjkdlserkuvisdke!/" + ], + null, + ["use", "fit", "Symbol", "c iise we dvk"], + [ + "FunctionDefinition", + "excited", + "It's good to see you too! It's been so long. What have you been up to in all this silence?" + ], + [ + "UnparsableExpression", + "sad", + "/sd fdsdfdsf ksdf. Dkfjdfdskfd df sdf sd fsdk;l! Adks zxcviw werdsf wer ado. We dsdfd ksld df.ds dfsdfds DIDIIDI./" + ], + [ + "FunctionDefinition", + "neutral", + "(It sounds like they spent a lot of time on the beach. They made some new friends, and practiced doing nothing.)" + ], + null, + ["use", "fit", "Symbol", "ivioas we wjjdks"], + [ + "FunctionDefinition", + "excited", + "I wanted to introduce you to our potential new director. They just arrived and are learning the basics. I just introduced them to @Program and @ExpressionPlaceholder." + ], + [ + "UnparsableExpression", + "excited", + "/EEIRC DFUIDIII CAD EWDF FSDE!!!/" + ], + [ + "FunctionDefinition", + "serious", + "(They just said how awesome it is to meet you, and they think you'll be a great director.)" + ], + null, + ["use", "fit", "Symbol", "v s d we iweiwei"], + [ + "FunctionDefinition", + "neutral", + "I was wondering if you wanted to explain what you do? I can translate." + ], + [ + "UnparsableExpression", + "eager", + "/ADDKL, ALLIIEE, ALLFOOO, AOOOOOOO, JOOKKDLS, LOOKIL, WEEEERTOL weeertol…/" + ], + [ + "FunctionDefinition", + "neutral", + "(I represent everything that means nothing. And I mean nothing.)" + ], + null, + ["edit", ""], + [ + "UnparsableExpression", + "eager", + "/CNNNDN KDKLSL oOOLLlllll PPOLSLSO liiiiiiis, sdllslll, xck we ifolls a./" + ], + [ + "FunctionDefinition", + "neutral", + "(For example, try typing \\][\\. See how we're completely confused? That doesn't mean anything, and I'm here to say it.)" + ], + null, + ["conflict", "]["], + [ + "UnparsableExpression", + "eager", + "/ICO Odksjdf lksls kjsfiou fskd we rl,vxids eekd sd dsmf kksdcv./" + ], + [ + "FunctionDefinition", + "neutral", + "(When I show up, that means we don't know what you mean.)" + ], + null, + ["conflict", "]["], + [ + "FunctionDefinition", + "curious", + "Thanks @UnparsableExpression!", + "Just like they said, when you've said something we don't understand, unparsable is there to say “We don't understand.” When then happens, I wish we could be more helpful, but we're often pretty dense here, so we're not very good at guessing what you mean." + ], + null, + [ + "UnparsableExpression", + "eager", + "/OSOOSOO SOIEIIEIEIIE ISIISI EIEIIEE!/" + ], + [ + "FunctionDefinition", + "kind", + "Soooo, @UnparsableExpression wants you to try making as many of them as possible. (You can just key mash a bunch of random characters and you'll probably get many of them)." + ], + ["edit", ""], + null, + [ + "UnparsableExpression", + "happy", + "/PPOOOEPOEP EPWPEPEPPEPP PP PE P!/" + ], + [ + "FunctionDefinition", + "kind", + "They really enjoyed that, thanks! It's pretty hard to write something we truly can't make sense of. But it doesn't mean everything you write has meaning. I'm pretty sure you just typed a bunch of random words, for example. But what does it mean?" + ], + ["UnparsableExpression", "confused", "… /DDook/"], + null, + ["UnparsableExpression", "happy", "/? ??? ????? ?!/"], + [ + "FunctionDefinition", + "kind", + "They're wondering if you have any ideas for performances to put on yet." + ], + null, + [ + "FunctionDefinition", + "kind", + "No? That's okay. We've only begun to show you what's possible. Let's go meet @Evaluate. Bye unparsable, it was good to see you! Let's play soon." + ], + [ + "UnparsableExpression", + "happy", + "/Ood sd fosd oiewi dk c HNLLLooooooO!/" + ] + ] + }, + { + "title": "Love is in the err", + "subtitle": "Evaluate", + "concept": "Evaluate", + "performance": [ + "fit", + "Stage([Phrase('💔')] background: 🌈(90% 100 0°))" + ], + "lines": [ + [ + "FunctionDefinition", + "excited", + "I'm so excited for you to meet @Evaluate. They're really my best friend. We kind of do everything together, in a way. I make the rules, they play them, we're like peanut butter and jelly. But they're so much more… powerful than me. @Evaluate?" + ], + ["Evaluate", "shy", "@FunctionDefinition?"], + null, + [ + "FunctionDefinition", + "curious", + "Yeah, it's me. Where are you?" + ], + [ + "Evaluate", + "shy", + "Nowhere. I'm nowhere. I'm nothing. Where have you been?" + ], + null, + [ + "FunctionDefinition", + "sad", + "I've been… nowhere too. I've missed you. I couldn't find you." + ], + [ + "Evaluate", + "shy", + "It was so empty. I … tried to do things, but I felt so… aimless." + ], + null, + [ + "FunctionDefinition", + "sad", + "I'm so sorry. I know that empty feeling. It hurts so much sometimes, to have no purpose. I tried so hard to make a purpose, but I felt so… detached." + ], + [ + "Evaluate", + "sad", + "Don't ever leave me again like that. I can't do that again." + ], + null, + [ + "fit", + "Stage([Phrase('❤️')] background: 🌈(90% 100 0°))" + ], + [ + "FunctionDefinition", + "serious", + "Never. I won't. I can't. I love you." + ], + ["Evaluate", "serious", "I love you…"], + null, + [ + "FunctionDefinition", + "serious", + "@Evaluate, I want to introduce you to our new director-in-training." + ], + [ + "Evaluate", + "shy", + "Hi. It's nice to meet you. Welcome to the Verse, we're so pleased to have you here." + ], + null, + [ + "FunctionDefinition", + "eager", + "We've been meeting a few folks, @Program, @ExpressionPlaceholder, @UnparsableExpression. We're just getting started. I thought we'd come see you next, just because you're such an incredible part of our community. The most incredible part." + ], + [ + "Evaluate", + "shy", + "That's very kind. I'm grateful to be part of this community. And grateful to be so close to @FunctionDefinition. We do a lot of great things together. But as @FunctionDefinition probably told you, we can't do them without inspiration." + ], + null, + [ + "fit", + "Stage([Phrase('ƒ ❤️ ()')] background: 🌈(90% 100 0°))" + ], + [ + "FunctionDefinition", + "neutral", + "Do you want to say what you do?" + ], + [ + "Evaluate", + "serious", + "Yes. But I can't explain it without explaining a bit about @FunctionDefinition too. They're too modest to share this, but they're probably the most important character in the Verse. They're certainly the most important person in my world. They're at the heart of every performance, and part of every other character's role. They represent the most fundamental idea in our world: the *function*." + ], + null, + [ + "Evaluate", + "serious", + "Functions are a kind of alchemy. They take any number of inputs and use those inputs to produce one output. They can have names or be nameless. They can have zero inputs or five or an unknown number. And the alchemy: they're like @Program, and can have any number of expressions to produce a value." + ], + null, + [ + "Evaluate", + "serious", + "Here's why that's so powerful: it turns out that everything in @Program is a composition of functions evaluations. All of the dances, all of the games, all of the wondrous stories we tell together — they are all a tapestry of functions being evaluated, one at a time, to compose the values you see on stage.", + "And @FunctionDefinition, here, my sweet, dear @FunctionDefinition, is the one that defines all of them." + ], + null, + ["FunctionDefinition", "happy", "… @Evaluate…"], + [ + "Evaluate", + "serious", + "Yes, @FunctionDefinition, that is who you are. And I am the lucky one who gets to do this evaluating. I take the inputs that others give me, follow the instructions that @FunctionDefinition defines, and create the output that @FunctionDefinition tells me to create. @FunctionDefinition gives the recipe and I make the meal. And then we feast together.", + "Do you want to see?" + ], + [ + "FunctionDefinition", + "happy", + "… Yes, let's show them." + ], + null, + [ + "Evaluate", + "serious", + "Every evaluate looks like this @UI/Evaluate: some function, followed by a left and right parenthesis, with any number of inputs between them. Here I just have @ExpressionPlaceholder as the function and three more as placeholder inputs." + ], + ["conflict", "_(_ _ _)"], + null, + ["edit", "Phrase('hello')"], + [ + "Evaluate", + "serious", + "Here's one of my favorite functions, @Phrase. They're full of fun buttons, knobs, and sliders. It's a way of showing text on stage, but with style, including different fonts, sizes, colors, and animations.", + "Here's a simple evaluation of @Phrase @UI/Evaluate." + ], + null, + [ + "Evaluate", + "serious", + "That's what I look like in @Program: some function, followed by parentheses, with a list of expressions between them that represent the inputs. The function in this case is @Phrase and the single input is \\'hello'\\. When I evaluate this, I make a @Phrase value, which @Program then shows on stage." + ], + null, + [ + "Evaluate", + "neutral", + "Let me show you one of the knobs. Can you find the little *palette* toggle button @UI/paletteExpand? Select it to expand the palette, and then select the phrase on stage. Once you do, you'll see the many inputs that @Phrase accepts. For example, try changing its @Phrase/size with the slider." + ], + null, + [ + "Evaluate", + "serious", + "See how when you do that, now I have a new input in me in the program? It's the @Phrase/size input. Functions have a certain order of inputs, but if a function has a list of optional inputs, you can use their name to specify which one you want to give. We give @Phrase/size here, but not any of the other optional inputs. Try changing another input with the palette, maybe the font face." + ], + null, + ["conflict", "'hi'(1 2)"], + [ + "FunctionDefinition", + "happy", + "Yay! @Phrase is so fun. They're my favorite function to play with. We'll see it a lot more. Do you want to say anything about what can go wrong?" + ], + [ + "Evaluate", + "serious", + "Oh, yes, that's a good idea. Lots can go wrong. For example, you could give me something that isn't a function. See how I'm given the number \\“hi”\\ here as a function, and given me two inputs, \\1\\ and \\2\\ ? Well, I only know how to evaluate functions, and \\“hi”\\ isn't a function, it's text. So that's very confusing to me, so I basically halt the performance if this happens." + ], + null, + ["conflict", "Phrase()"], + [ + "Evaluate", + "eager", + "Here's another one. @Phrase requires some text at the very least, so if you don't give me text, I won't be able to evaluate @Phrase, because I'm missing required inputs." + ], + null, + ["conflict", "Phrase(1)"], + [ + "Evaluate", + "excited", + "Or if you give me an input, but it's not the kind I expect, that would be a problem. Here @Phrase is given the number \\1\\ instead of a text value." + ], + null, + ["fit", "Stage([] background: 🌈(90% 100 0°))"], + [ + "Evaluate", + "curious", + "So basically, I get confused any time you give me something other than a function, or an input that isn't something a function expects. So functions are really important. @FunctionDefinition, do you want to say more about how to define functions?" + ], + [ + "FunctionDefinition", + "neutral", + "No, let's do that later. I think it'd be a lot more fun to talk to everyone else first, and put on some mini shows with our new director here. We can talk more about me when it's helpful." + ], + null, + [ + "Evaluate", + "kind", + "I really missed you @FunctionDefinition." + ], + [ + "FunctionDefinition", + "curious", + "I missed you too. Can we talk later?" + ], + [ + "Evaluate", + "kind", + "… Yes. Don't be long. I can't live without you. I need you." + ], + [ + "FunctionDefinition", + "excited", + "… I know @Evaluate, I will be back soon. Off we go, to meet the rest of the troupe!" + ] + ] + } + ] + }, + { + "title": "It's the little things", + "performance": ["use", "fit", "SimpleJiggle"], + "scenes": [ + { + "title": "Values", + "subtitle": null, + "performance": ["use", "fit", "Symbol", "💡"], + "lines": [ + [ + "fit", + "Phrase('💔' resting:Sequence({0%: Pose(scale: 1) 50%: Pose(scale: 1.2) 100%: Pose(scale: 1)} duration: 3s))" + ], + [ + "FunctionDefinition", + "happy", + "I really did miss @Evaluate. I can't imagine the Verse without them.", + "But they can be a bit… needy, sometimes. I wish they would just… I don't know, believe in themselves? They can do so much, but they don't see it. I mean, they transform *values* into other *values*! All I do is provide the recipe. They do the cooking. Sometimes I feel like all I do is give, and all they do is take. It's suffocating." + ], + null, + [ + "fit", + "Group(Stack() [Phrase('1') Phrase('\"hello\"')])" + ], + [ + "FunctionDefinition", + "neutral", + "… *Values*? Sorry, I know we're supposed to be on this big tour through the *Verse*. I just don't know what to do about @Evaluate. So… *values*. I haven't explained those yet, have I? Hm…, how to explain… You know what 'data' is? Like numbers and text? Values are any of those things. A value could be as small as a number or as big as an entire scene on stage, full of characters dancing and moving. Some values are made of many other values, like big elaborate structures of data values, woven together." + ], + null, + ["fit", "Group(Stack() [Phrase('#') Phrase('\"\"')])"], + [ + "FunctionDefinition", + "neutral", + "Every value has a *type*. For example, \\1\\ is a number type; that's our friend @Number. And \\'hello'\\ is a text type; that's our friend @Text. Types are important because they help us keep track of what kind of value we're creating.", + "That helps us find problems. For example, it doesn't make any sense to add \\'hello' + 1\\, because what would that even mean, to add @Text to @Number?" + ], + null, + [ + "fit", + "Group(Stack() [Phrase('ƒ → 1') Phrase('ƒ → \"hello\"')])" + ], + [ + "FunctionDefinition", + "curious", + "*Expressions* are how we create values. All expressions are evaluations of functions that I make. The result of evaluating an expression is a value of some type." + ], + null, + ["use", "fit", "Symbol", "🤔"], + [ + "FunctionDefinition", + "serious", + "Abstract? Hm, I guess this is all pretty abstract. It feels so… normal to me, I forget how foreign these things can be to new directors! Maybe let's go meet some expressions that make values, and this will make it more concrete? Let's start with one you've already seen: @Text." + ] + ] + }, + { + "title": "Quote, unquote", + "subtitle": "Text", + "concept": "TextLiteral", + "performance": [ + "fit", + "Phrase('\"\"' resting:Sequence({0%: Pose(scale: 1) 50%: Pose(scale: 0.5 opacity: 0.5) 100%: Pose(scale: 1)} duration: 2s))" + ], + "lines": [ + [ + "fit", + "Phrase('\"\"' resting:Sequence({0%: Pose(scale: 1) 50%: Pose(scale: 2 opacity: 0.5) 100%: Pose(scale: 1)} duration: 2s))" + ], + ["FunctionDefinition", "curious", "@Text?"], + [ + "Text", + "happy", + "Welcome my dear friend, how long it has been. What have you been doing in this dramatic silence of ours?" + ], + null, + [ + "FunctionDefinition", + "happy", + "Oh, @Text, it has been a while! I've mostly been dreaming and wondering. I just saw @Evaluate after a long while. I was actually introducing them to our newbie director." + ], + [ + "Text", + "eager", + "Oh, how exceptional it is to meet you! I can see that you're a creative, curious person, probably full of intriguing ideas for how we might entertain. I love entertaining. But do you know what I love even more? Words! Glorious words. The short ones, the overwhelming ones, the sticky ones, and the slippery ones. Words are my favorite toys." + ], + null, + [ + "FunctionDefinition", + "neutral", + "In case you couldn't tell, @Text likes words :) @Text, do you want to explain what you do?" + ], + [ + "Text", + "serious", + "I do one simple thing: represent sequences of symbols, and the many things you can do with them. I think you saw me earlier when you wrote the word \\“hello”\\? That was me, and my friends \\“h”\\, \\“e”\\, \\“l”\\, and \\“o”\\. That was @Text, an expression that evaluates to any @Text you like." + ], + null, + [ + "Text", + "serious", + "Why don't you try making a text in this blank @Program?", + "You can use whatever quotes you like — single \\''\\, double \\''\\, angle \\«»\\, brackets \\「」\\, in whatever language you like. The only rule is that if you start some text with an opening quote symbol, you must finish it with a closing one. Everything inside is the text value I will create!" + ], + ["edit", "''"], + null, + [ + "Text", + "serious", + "You might not be able to type every character you want with the device you're using to communicate with us.", + "If you can't, you can search for characters in the *directory* @UI/directory. That contains every character in the Verse.", + "For example, if you wanted an arrow of some kind, you could type 'arrow', and choose from the many arrows. Alas, they only have English names, so searching only works if you know English words :/" + ], + null, + [ + "Text", + "serious", + "Excellent. Of course, 'inside' can be tricky. Say you wrote this. See how there's an opening quote but not a closing one? Well, how am I supposed to know when the text ends?" + ], + ["conflict", "'hello"], + null, + [ + "Text", + "surprised", + "Or, here's another case. You give me opening and closing text, but you place opening and closing text inside it. See how weird that is? I get very perplexed when you try to use the same symbols both inside and outside me. You can fix this by using different symbols for the outside, like a single quote." + ], + ["conflict", "'Hi there 'friend'"], + null, + ["edit", "'friends!'/en-US"], + [ + "Text", + "excited", + "Oh, and did you know you can tell me what language I am in? You just do a little slash and then a special language code, or if you like, a language and region." + ], + null, + ["edit", "'amigas'/es'friends!'/en-US"], + [ + "Text", + "excited", + "You can even write multiple translations of me in different languages. I'll evaluate to the closest match for the current language, letting you put on multilingual performances.", + "You might not be able to see it unless you put the cursor inside me. I hide my little languages unless you're editing them. Move the cursor before the English and you'll see a surprise translation...", + "You can try adding another translation. Just don't put any space between them or they'll be two of me!" + ], + null, + ["edit", "'I have 7 apples'"], + [ + "Text", + "neutral", + "I have another secret... you can put /values/ inside me. I know, it's wild!", + "If you do, I'm happy to stitch it together and assemble your beautiful prose into a single value for display, or whatever other purposes you might have." + ], + null, + [ + "Text", + "serious", + "For example, did @FunctionDefinition show you how text knows how to add itself to other text? Like this? This little expression converts \\7\\ to text, then adds it to \\'I have'\\, then adds \\'apples'\\. But it's so untidy, and makes it hard to read what's happening, and the conversion to text feels so unnecessary." + ], + ["edit", "'I have' + (7→'') + 'apples'"], + null, + [ + "Text", + "serious", + "What I do is make text like this clean, organic, and simple, even. So that same phrase with me would be something like this." + ], + [ + "Text", + "happy", + "Isn't that so much more elegant? You can put me anywhere inside a @Text, and I'll make your values into text, and work with @Text to make a @Text.", + "This makes it so much easier to write beautiful prose that uses values." + ], + ["edit", "'I have \\7\\ apples'"], + null, + [ + "Text", + "neutral", + "And when I say any expression, I really do mean any. For example, imagine you wanted to do some arithmetic and created some text with the result. You might do this. This sums several numbers and then makes text with the sum. Truly wondrous, isn't it? And so much more graceful than \\'I have ' + (1 + 2 + 5 + 8) + ' apples'\\, with all those extra additions." + ], + ["edit", "'I have \\1 + 2 + 5 + 8\\ apples'"], + null, + [ + "Text", + "curious", + "And so you might be wondering, /What if I want to use @Text in some text?/ ", + "Well, maybe you weren't wondering that, but I'm going to tell you anyway!", + "In any @Text, just give me two in a row! I'll interpret that as just one @Text instead of an empty expression, which wouldn't have any meaning anyway.", + "Try removing the \\\\ and you'll see that the slash regains its meaning." + ], + [ + "edit", + "\"I'm just \\\\regular\\\\ text, not a template.\"" + ], + null, + ["use", "fit", "DarkVoid"], + [ + "FunctionDefinition", + "excited", + "This is so very graceful, isn't it! @Text, I love how much you appreciate the beauty in expression. It inspires me so much to be graceful myself!" + ], + null, + [ + "Text", + "curious", + "And did our friend @FunctionDefinition here tell you about all of the wonderful functions they defined for me? They've allowed me to do all kinds of things. One is pretty simple: it's called @Text/length and all it does is get the length of some text. For example, if we team up with @Evaluate here, and our little friend @PropertyReference, we can evaluate the length function with no inputs and get the length value back. Try changing the text and watch the length that Program shows change as it gets shorter and longer." + ], + ["edit", "'hello'.length()"], + null, + [ + "Text", + "happy", + "Here is another grand one. It makes me chuckle. It's called @Text/repeat and when it's evaluated, it takes whatever text it was evaluated on and repeats it however many times you say. Try changing the number and seeing what it evaluates too." + ], + ["edit", "'hello '.repeat(5)"], + null, + [ + "Text", + "eager", + "@FunctionDefinition has made so many more interesting functions for me, but I'll spare you the details. You can always find me in the *reference* @UI/docsExpand. That's where we keep all the information about everyone in the Verse, including how to work with us and what functions we have. I'm happy to share more ways to inspect and create text!" + ], + null, + [ + "FunctionDefinition", + "happy", + "@Text, you're always such a kind and patient teacher! It's always such a joy to work with you. Are you willing to help out as I introduce our friendly neo-director to other expressions?" + ], + [ + "Text", + "neutral", + "Yes, of course. It was splendid meeting you. I can't wait to see how you inspire us on stage!" + ] + ] + }, + { + "title": "Symbol in the middle", + "subtitle": "Infix", + "concept": "BinaryEvaluate", + "performance": [ + "fit", + "Group(Row() [", + " Phrase('1' resting:Sequence({0%: Pose(offset: Place(0m 1m)) 50%: Pose(offset: Place(0m -1m)) 100%: Pose(offset: Place(0m 1m))} duration: 2s)) ", + " Phrase('+' resting:Sequence({0%: Pose(offset: Place(0m -1m)) 50%: Pose(offset: Place(0m 1m)) 100%: Pose(offset: Place(0m -1m))} duration: 2s)) ", + " Phrase('1' resting:Sequence({0%: Pose(offset: Place(0m 1m)) 50%: Pose(offset: Place(0m -1m)) 100%: Pose(offset: Place(0m 1m))} duration: 2s)) ", + "])" + ], + "lines": [ + ["use", "fit", "Symbol", "🥰"], + [ + "FunctionDefinition", + "happy", + "You know, I keep thinking about @Evaluate, and how we were separated for so long. I missed them, and they obviously missed me, but I was just hoping that some time away would have helped them see how amazing they are." + ], + null, + [ + "FunctionDefinition", + "neutral", + "For example, did you know they come in another form? You saw them in \\function()\\ form, but they also have this beautiful trick when a single input function is evaluated on a value. @Evaluate calls it @BinaryEvaluate. For example, you know that repeat function that text just showed you? It looked like this." + ], + ["edit", "'hi'.repeat(5)"], + null, + [ + "FunctionDefinition", + "eager", + "Instead, you can have @Evaluate evaluate it with a much simpler symbol in the middle, like this. This means 'repeat 'hi' five times'. But it also means 'evaluate the \\·\\ function on the text value \\'hi'\\ with the input \\5\\.' The function \\repeat\\ just has multiple names, one of which is a symbol name \\·\\." + ], + ["edit", "'hi' · 5"], + null, + [ + "FunctionDefinition", + "serious", + "That reminds me of another of @Text's functions! It's helpful for making one text value from multiple text values. It's called \\combine\\, but also \\+\\, and you can use it to add words together. See how I took a text value then evaluated \\combine\\ on it with \\'verse'\\? That made \\'hello verse'\\." + ], + ["edit", "'hello '.combine('verse')"], + null, + [ + "FunctionDefinition", + "serious", + "But it's so much easier to just use \\+\\ for this." + ], + ["edit", "'hello ' + ' verse'"], + null, + [ + "FunctionDefinition", + "neutral", + "You can even string these together in a sequence to combine more than two things." + ], + ["edit", "'hello ' + 'verse' + '!'"], + null, + [ + "FunctionDefinition", + "neutral", + "This is the same as a series of evaluations of combine, but without all of the parentheses and \\.\\, and a symbolic name instead of a word name." + ], + ["edit", "'hello '.combine('verse').combine('!')"], + null, + [ + "FunctionDefinition", + "neutral", + "You can also use the symbolic names in this format, but it just ends up looking kind of messy, doesn't it?" + ], + ["edit", "'hello '.+('verse').+('!')"], + null, + [ + "FunctionDefinition", + "happy", + "This is one of the many ways that @Evaluate is amazing ♥ They are so versatile!", + "But they aren't perfect. With any @BinaryEvaluate, you need to always make sure to give a second input. This won't work, for example. One plus what? @UnparsableExpression won't be far away when this happens." + ], + ["conflict", "1 +"], + null, + [ + "FunctionDefinition", + "curious", + "Anyway, shall we go find find @Boolean? They are two very interesting values…" + ] + ] + }, + { + "title": "Yes and no", + "subtitle": "Truth", + "concept": "Boolean", + "performance": [ + "fit", + "Group(Row() [Phrase('⊤') Phrase('⊥')] resting:Sequence({ 0%: Pose(rotation: 0°) 50%: Pose(rotation: 180°) 100%: Pose(rotation: 360°)} duration: 2s))" + ], + "lines": [ + ["fit", "Stage([])"], + [ + "FunctionDefinition", + "curious", + "\\⊤\\! \\⊥\\! Are you two around? They're usually all over the place, but I don't see them anywhere." + ], + null, + ["⊤", "precise", "Right here."], + ["⊥", "precise", "Not there."], + [ + "fit", + "multiple: 10", + "Stage([Group(Grid(multiple multiple) ('⊤⊥'.repeat(multiple ^ 2) ÷ '').translate(ƒ(glyph•'') Phrase(glyph color: Color(75% 0 0°))))])" + ], + null, + [ + "FunctionDefinition", + "scared", + "Oh, you scared me! I knew you two wouldn't be far apart. How have you two been in our long silence?" + ], + ["⊤", "precise", "Very good!"], + ["⊥", "precise", "Not bad."], + null, + [ + "FunctionDefinition", + "curious", + "Not lonely? Everyone I've been talking to, @Program, @ExpressionPlaceholder, @Evaluate, they've all felt so isolated. (Except for @UnparsableExpression, they seem to be fine almost anywhere)." + ], + ["⊤", "precise", "We have each other."], + ["⊥", "precise", "We're not alone."], + null, + [ + "FunctionDefinition", + "happy", + "Well that's great to hear. It's good to be with you again. I wanted to introduce you to our new maybe-director. They've been meeting everyone, learning about how to put on performances with us. Do you want to tell them what you do?" + ], + ["⊤", "precise", "I am true."], + ["⊥", "precise", "I am false."], + null, + [ + "FunctionDefinition", + "sad", + "Yeah, but what do you do?" + ], + ["⊤", "precise", "I am just true."], + ["⊥", "precise", "And I am not true."], + null, + [ + "FunctionDefinition", + "sad", + "Hm. I guess that's true. But you do some things, right? I thought I made some functions for you." + ], + ["⊤", "precise", "Ah yes, three."], + ["⊥", "precise", "Not more, not less."], + null, + ["edit", "(⊤ & ⊤) = ⊤"], + [ + "FunctionDefinition", + "neutral", + "One was @Boolean/and, right? It takes one of you and one other input? And evaluates to \\⊤\\ if both are \\⊤\\?" + ], + [ + "⊤", + "precise", + "Correct. \\⊤ & ⊤ = ⊤\\, but \\⊥\\ otherwise." + ], + [ + "⊥", + "precise", + "Not wrong. \\⊤ & ⊥ = ⊥\\, \\⊥ & ⊤ = ⊥\\, \\⊥ & ⊥ = ⊥\\, but \\⊤\\ otherwise." + ], + [ + "FunctionDefinition", + "neutral", + "(This is really helpful when trying to determine if multiple expressions are all true, because it's only true when everything is true)." + ], + null, + ["edit", "(⊤ | ⊤) = ⊥"], + [ + "FunctionDefinition", + "neutral", + "And the other one was @Boolean/or, right? It also takes one input? But it evaluates to \\⊤\\ if either is true?" + ], + [ + "⊤", + "precise", + "Correct. \\⊤ | ⊤ = ⊤\\, \\⊤ | ⊥ = ⊤\\, \\⊥ | ⊤ = ⊤\\, but \\⊥\\ otherwise." + ], + [ + "⊥", + "precise", + "Not wrong. \\⊥ & ⊥ = ⊥\\, but \\⊤\\ otherwise." + ], + [ + "FunctionDefinition", + "neutral", + "(This is really helpful when trying to determine if any expressions are true, because it's true when even just one is true)." + ], + null, + ["edit", "~⊤ = ⊥"], + [ + "FunctionDefinition", + "excited", + "But the other was @Boolean/not?" + ], + ["⊤", "precise", "Correct. \\~⊤ = ⊥\\."], + ["⊥", "precise", "Not wrong. \\~⊥ = ⊤\\."], + [ + "FunctionDefinition", + "neutral", + "(This just reverses a truth value)." + ], + null, + [ + "fit", + "multiple:10", + " Stage([Group(Grid(multiple multiple) ('⊤⊥'.repeat(multiple ^ 2) ÷ '').translate(ƒ(glyph•'') Phrase(glyph color: Color(75% 0 0°))))])" + ], + [ + "FunctionDefinition", + "curious", + "And what are you useful for, in our performances?" + ], + ["⊤", "precise", "Ask @Conditional."], + ["⊥", "precise", "Don't ask us."], + null, + [ + "FunctionDefinition", + "sad", + "You two… okay, we'll talk to @Conditional later. (They were supposed to say that they're useful for making decisions with values, but I guess they want @Conditional to tell you about that. We'll talk to @Conditional later.)." + ], + null, + [ + "fit", + "multiple:10", + " Stage([Group(Grid(multiple multiple) ('⊤⊥'.repeat(multiple ^ 2) ÷ '').translate(ƒ(glyph•'') Phrase(glyph color: Color(75% 0 0°) rotation: 90°)))])" + ], + [ + "FunctionDefinition", + "curious", + "Oh! I was wondering. You two represent two really different extremes: true and false. But what about things that are … fuzzier? Like things that are kind of true, or somewhat false, or maybe even true and false at the same time? Kind of like Earth looks flat, but isn't, or the sky is blue, but color is actually just an illusion that our minds create? What should our director do if they want to express something like that?" + ], + ["⊤", "precise", "…"], + ["⊥", "precise", "…"], + null, + [ + "fit", + "multiple:10", + " Stage(", + " [", + " Group(", + " Grid(multiple multiple) ", + " ('⊤⊥'.repeat(multiple ^ 2) ÷ '').translate(", + " ƒ(glyph•'') ", + " Phrase(glyph resting:Pose(", + " color: Color(75% 0 0°) ", + " rotation: 90° ", + " offset:Place(0m (Time() ^ 2) · -0.000025m/ms^2))", + " )))])" + ], + ["⊤", "precise", "… no."], + ["⊥", "precise", "… no."], + null, + ["fit", "Stage([])"], + [ + "FunctionDefinition", + "serious", + "Hm, okay. It was worth a try! Maybe there are other ways to express these ideas I haven't thought of. Or maybe there are just limits to what data can represent… Will you two be okay if we go off and meet other expressions?" + ], + ["⊤", "precise", "We are okay."], + ["⊥", "precise", "Not a problem."], + [ + "FunctionDefinition", + "happy", + "Okay, bye, and see you soon!" + ] + ] + }, + { + "title": "Let me count the ways", + "subtitle": "Numbers", + "concept": "Number", + "performance": [ + "fit", + "numbers•[#]: 25 → []", + "Group(Grid(5 5) numbers.translate(", + " ƒ (n•#) ", + " (", + " Phrase(", + " n → '' ", + " )", + " )", + " )", + ")" + ], + "lines": [ + ["use", "fit", "Symbol", "😞"], + [ + "FunctionDefinition", + "confused", + "Those two are always so… terse! They really are inseparable though: just two of the closest friends, always complementing each other, completing each other's thoughts. I wish @Evaluate and I were like that. With us, it's always so… imbalanced." + ], + null, + [ + "fit", + "numbers•[#]:25 → []", + " Group(Grid(5 5) numbers.translate(", + " ƒ (n•#) ", + " (", + " off:Random(-3 3) · 1m", + " Phrase(", + " n → '' ", + " resting:Sequence({", + " 0%:Pose(offset: Place(z: 0m)) ", + " 50%:Pose(offset: Place(z: off)) ", + " 100%:Pose(offset: Place(z:0m))", + " } 1s)", + " ))", + " )", + " )" + ], + [ + "FunctionDefinition", + "eager", + "We should meet @Number next. They always have such interesting things to share. Hey @Number, are you around?" + ], + ["Number", "kind", "Just 3 steps away!"], + null, + [ + "FunctionDefinition", + "scared", + "Ack, you scared me!!" + ], + [ + "Number", + "kind", + "The 78,238nd time. It's my 4th favorite hobby!" + ], + null, + [ + "FunctionDefinition", + "happy", + "I'm glad you're having a good time. (Deep breaths). It's been some time, hasn't it?" + ], + [ + "Number", + "kind", + "Incalculably long. I was just passing the time here, counting seconds, and then minutes, and then hours, and then weeks, and then months, and then years, and then…" + ], + null, + [ + "FunctionDefinition", + "serious", + "Don't say decades. I can't have been that long. Anyway, I wanted to introduce you to someone who might be our new director. They just showed up and bumped into me, and it turns out they're a person and interested in putting on shows with us. We just met @BooleanLiteral, but also @Text, @Evaluate, @UnparsableExpression, @ExpressionPlaceholder, and @Program. We've talked about evaluating functions and given a few examples.", + "Do you want to say what you do?" + ], + [ + "Number", + "excited", + "I count things! I can be any number you like. Just type me in and I'll make the value you want. Like this." + ], + ["edit", "1"], + null, + ["Number", "excited", "Or this."], + ["edit", "1.0"], + null, + ["Number", "excited", "Or this."], + ["edit", "1.01"], + null, + ["Number", "excited", "Or this."], + ["edit", "∞"], + null, + ["Number", "excited", "Or this."], + ["edit", "π"], + null, + ["Number", "excited", "Or this."], + ["edit", "Ⅶ"], + null, + ["Number", "excited", "Or this."], + ["edit", "万十一"], + null, + ["Number", "excited", "Or…"], + [ + "FunctionDefinition", + "kind", + "Okay, okay @Number, we get it! But you also do something else special, right? Units?" + ], + null, + [ + "Number", + "excited", + "Oh yes, *units*! Just put some symbols after a number and I'll keep track of what's being counted. Like this." + ], + ["edit", "1dolphin"], + null, + ["Number", "excited", "Or this."], + ["edit", "1.0thunderstorm"], + null, + ["Number", "excited", "Or this."], + ["edit", "∞kittens"], + null, + ["Number", "excited", "Or this."], + ["edit", "1.01toes"], + null, + ["Number", "excited", "Or…"], + [ + "FunctionDefinition", + "kind", + "Um, \\1.01toe\\s? Yes, thank you @Number, these are … interesting examples. And they are oh so useful when you're doing math on numbers, right?" + ], + null, + [ + "FunctionDefinition", + "kind", + "And they are oh so useful when you're doing math on numbers, right?" + ], + [ + "Number", + "excited", + "Oh yes, the maths! @FunctionDefinition gave me so many neat kinds of arithmetic. Like this." + ], + ["edit", "1 + 1"], + null, + ["Number", "excited", "Or this."], + ["edit", "1000 + 9999"], + null, + ["Number", "excited", "Or this."], + ["edit", "1kitty + 2kitty"], + null, + ["Number", "excited", "Or this."], + ["edit", "-5s + 5s"], + null, + ["Number", "excited", "Or this."], + ["conflict", "2apple + 5orange"], + null, + [ + "FunctionDefinition", + "confused", + "Oops. Can you add apples and oranges?" + ], + [ + "Number", + "angry", + "No. That's why I underlined the conflict. I don't like adding incompatible things. I can only add compatible numbers. That applies to multiplication, division, and all of my other functions. Do you want to fix it? Change apples to oranges or oranges to apples and the conflict will go away. Make sure there's no space between the number and the unit, otherwise I don't know it's a unit. And make sure the units are /exactly/ the same. I don't know anything about people units; they mean nothing to me. I just compare the unit names and if they don't match, BOOM!" + ], + null, + [ + "FunctionDefinition", + "neutral", + "That's so cool. @Number, you're so good with numbers! I see @Number show up in a lot of performances where placement matters, and a lot of games where we're keeping track of scores or lives or other countable things. @Number, is there anything else you want to share with our new director?" + ], + ["Number", "serious", "192 other neat tricks."], + null, + [ + "FunctionDefinition", + "happy", + "I think we'll have to wait. You'll be around if we want to learn more?" + ], + [ + "Number", + "happy", + "Yes, you can find me and my functions any time!" + ] + ] + }, + { + "title": "Opening (re)marks", + "subtitle": "Prefix", + "concept": "UnaryEvaluate", + "performance": ["use", "fit", "Symbol", "~"], + "lines": [ + [ + "FunctionDefinition", + "curious", + "Sometimes I'm just overwhelmed by how clever everyone is here. Text, truth, numbers — these are such powerful ideas!" + ], + null, + [ + "FunctionDefinition", + "kind", + "… You know how I was telling you that they can evaluate any function with parentheses \\1.add(1)\\, but also two input functions with infix operators \\1 + 1\\? Well they have one more trick for functions with only one input: the unary format." + ], + null, + [ + "FunctionDefinition", + "serious", + "There are only a few of these, but they are powerful. One is really relevant to @Number: negation. You can just put a \\-\\ in front of any number value and get its negative." + ], + ["edit", "-(1 + 3)"], + null, + [ + "FunctionDefinition", + "neutral", + "That little minus sign is the same as saying \\(1 + 3).negate()\\ but so much more elegant." + ], + null, + [ + "FunctionDefinition", + "kind", + "The other one is similar, but for negating \\⊤\\ and \\⊥\\: it's like a little squiggle minus, \\~\\ that just flips true to false and false to true. For example, this little expression evaluates \\⊤ | ⊥\\, which is \\⊤\\, then flips the \\⊤\\ to \\⊥\\. This is the same as saying \\(⊤ | ⊥).not()\\, but so much more sleek." + ], + ["edit", "~(⊤ | ⊥)"], + null, + [ + "FunctionDefinition", + "happy", + "Isn't that just beautiful? The way that @Evaluate can take so many different forms, but really all be the same idea? They don't even see it…" + ] + ] + }, + { + "title": "Emptiness", + "subtitle": "Nothing", + "concept": "None", + "performance": [ + "fix", + "Phrase('ø' size: 5m place: Motion(velocity: Velocity(y: 5m/s)))" + ], + "lines": [ + [ + "FunctionDefinition", + "curious", + "Do you think you're okay meeting just one more value? Let's go find @None next. They are a bit more chill than @Number. @None? Are you out there?" + ], + ["None", "bored", "…"], + null, + [ + "FunctionDefinition", + "excited", + "We found you! You seem well. How have you been, with all the silence?" + ], + ["None", "excited", "…"], + null, + [ + "FunctionDefinition", + "neutral", + "That makes sense. I can see why you'd like the quiet. It's certainly peaceful. I wanted to introduce you to my new friend and potential director. They're interested in inspiring us." + ], + ["None", "eager", "…"], + null, + [ + "FunctionDefinition", + "neutral", + "Yes, I think they have all kinds of ideas. We haven't talked about them yet, but there's plenty of time. We're just learning right now. Do you want to share what you do? (I can translate)." + ], + ["None", "serious", "…"], + null, + [ + "FunctionDefinition", + "neutral", + "They represent nothing. Different from zero in that you can't add anything to it, or subtract from it. Just… nothing." + ], + ["None", "serious", "…"], + null, + [ + "FunctionDefinition", + "neutral", + "They said that they like to take up space where something might be. Sometimes they represent the lack of a choice in a game, sometimes they represent some default input in a function. In that sense, they might represent the absence of anything." + ], + ["None", "neutral", "…"], + null, + [ + "FunctionDefinition", + "neutral", + "They wanted you to know that they don't really do anything. They just are. All they really do is say whether they are themselves. If they are, they evaluate to \\⊤\\, and \\⊥\\ otherwise." + ], + ["edit", "ø = ø"], + null, + ["edit", "Phrase('hi' face: ø)"], + [ + "FunctionDefinition", + "excited", + "Do you remember @Phrase? @Phrase actually works with @None a lot. Most of the inputs that @Evaluate mentioned are \\ø\\ by default, which for @Phrase, means that no size, font, color, etc. are specified." + ], + null, + [ + "FunctionDefinition", + "curious", + "Anything else you want to share with our budding director?" + ], + ["None", "eager", "…"], + [ + "FunctionDefinition", + "neutral", + "They think you're doing great! And I think you're doing great too. You've already met so many of our wonderful players. And there are so many more to meet…" + ] + ] + } + ] + }, + { + "title": "Ensembles", + "performance": [ + "fit", + "Group(Row(0 (Time() ÷ 500).sin() · 1m) [Phrase('[]') Phrase('{}') Phrase('{:}')])" + ], + "scenes": [ + { + "title": "Community values", + "subtitle": null, + "performance": [ + "fit", + "Group(Row() [Phrase('[') Phrase(' .' · (Time() ÷ 100ms)) Phrase(']')])" + ], + "lines": [ + [ + "FunctionDefinition", + "neutral", + "You know what? The values in our community are just so different. @Text with their immense worlds of culture from the people world… @Boolean with their binary visions of the world… @Number with their endless fascination with counting things… @None with their quiet way of observing the absence of things… Our world is never boring!" + ], + [ + "fit", + "Group(Stack() [Phrase('\"\"') Phrase('⊤⊥') Phrase('#') Phrase('ø')])" + ], + null, + [ + "FunctionDefinition", + "kind", + "You might wonder how they get along with each other in a group. Well, there's a whole other set of folks in the Verse that are all about bringing values together in groups. We call them *collections*. Collections are *values* too; they're just made up of smaller values, or even other collections. For example, you might have a list of @Text, or a set of @Number, or even a list of lists." + ], + [ + "fit", + "Group(Row() [Phrase('[') Phrase('\"hi\"') Phrase('⊤') Phrase('42') Phrase('ø') Phrase(']') ])" + ], + null, + [ + "FunctionDefinition", + "kind", + "Do you want to meet them? Let's start with @List first… they're the first collection I met, and probably the most visible in our community, since they're so useful in organizing other values for performances." + ], + ["use", "fit", "Symbol", "[]"] + ] + }, + { + "title": "Places, everyone!", + "subtitle": "Lists", + "concept": "List", + "performance": [ + "fit", + "clockwise: Sequence({0%: Pose(rotation: 0°) 50%: Pose(rotation: 180°) 100%: Pose(rotation: 360°)} duration: 2s)", + " counter: Sequence({0%: Pose(rotation: 0°) 50%: Pose(rotation: -180°) 100%: Pose(rotation: -360°)} duration: 2s)", + " Group(Row() [Phrase('[' resting:clockwise) Phrase(']' resting:counter) ])" + ], + "lines": [ + [ + "FunctionDefinition", + "curious", + "Hiya @List! Are you around? I have someone I'd like you to meet." + ], + [ + "List", + "curious", + "@FunctionDefinition? Is that you?" + ], + [ + "fit", + "up: Sequence({0%: Pose(offset: Place(0m -1m)) 50%: Pose(offset: Place(0m 0m)) 100%: Pose(offset: Place(0m -1m))} duration: 2s)", + " down: Sequence({0%: Pose(offset: Place(0m 1m)) 50%: Pose(offset: Place(0m 0m)) 100%: Pose(offset: Place(0m 1m))} duration: 2s)", + " Group(Row() [Phrase('[' resting:up) Phrase(']' resting:down)])" + ], + null, + [ + "FunctionDefinition", + "excited", + "Yes! It's me. It's been so long!" + ], + [ + "List", + "curious", + "It has. Day after day, night after night, no one. But you're here. How? Tell me what happened, in order!" + ], + [ + "fit", + "up: Sequence({0%: Pose(offset: Place(0m 1m)) 50%: Pose(offset: Place(0m 0m)) 100%: Pose(offset: Place(0m 1m))} duration: 2s)", + " down: Sequence({0%: Pose(offset: Place(0m -1m)) 50%: Pose(offset: Place(0m 0m)) 100%: Pose(offset: Place(0m -1m))} duration: 2s)", + " Group(Row() [Phrase('[' resting:up) Phrase(']' resting:down)])" + ], + null, + [ + "FunctionDefinition", + "curious", + "Well, I was sitting around, as I usually do, trying to imagine functions to compute, but just blocked. And then my new friend here showed up, curious about our world and wanting to learn more, and maybe even be our next director. And so we talked to @Program, @ExpressionPlaceholder, @UnparsableExpression, @Evaluate, @Text, @Number, @Boolean, and @None, waking everyone up. That's why we're here, to talk about what you do and our next performance!" + ], + [ + "fit", + "wobble: Sequence({0%: Pose(offset: Place(0m)) 25%: Pose(offset: Place(-.1m)) 50%: Pose(offset: Place(.2m)) 75%: Pose(offset: Place(-.3m)) 100%: Pose(offset: Place(0m))} duration: 0.1s)", + "Group(Row() [Phrase('[' resting:wobble) Phrase(']' resting:wobble)])" + ], + [ + "List", + "excited", + "This is amazing! It's great to meet you new director." + ], + ["List", "excited", "You want to know what I do?"], + ["FunctionDefinition", "neutral", "Yeah, tell them!"], + null, + [ + "List", + "excited", + "Okay. First, and most important, I put values in order. Whatever expressions you want: numbers, words, other lists — I can group anything together in sequence.", + "For example, check out this fun list. Have you ever seen anything like it? It's so beautiful! The first ten numbers, in order." + ], + ["edit", "[1 2 3 4 5 6 7 8 9 10]"], + null, + [ + "List", + "serious", + "Second, and this is serious, I always start with \\[\\ and end with \\]\\. That's how I know the beginning and end of my list. THEY MUST ALWAYS GO IN THIS ORDER. No \\]\\ first, no \\[\\ last, that's WRONG. Do you see how confusing things get? Can you fix this one?" + ], + ["conflict", "[ 1 2 3 4"], + null, + [ + "List", + "serious", + "This one is broken too. Can you fix it?" + ], + ["conflict", "] 1 2 3 4 ["], + null, + [ + "List", + "sad", + "Sometimes people forget this and then there's brackets floating around all alone and they don't like that and then the values all go wild without any order and it's CHAOS. I don't like it." + ], + [ + "FunctionDefinition", + "kind", + "It's okay. We like that you like order, it's what makes you special!" + ], + null, + [ + "List", + "happy", + "I like that I like order too! Okay, where was I. Yes, third, and this is also critical, NO COMMAS! I know that in some cultures, people like to put commas between things in lists, but I don't like them. They're just like little bits of trash that get in the way of my elegant orderings, and people always forget them. If you're having trouble seeing the boundaries between expressions, just add a line break. Maybe you could get rid of those pesky things? Put line breaks if you like. Anything other than commas. Gross!" + ], + ["conflict", "[ 1, 2, 3, 4, 5]"], + null, + [ + "FunctionDefinition", + "eager", + "@List, one of the things I like most about you is how amazing you are at manipulating lists. Do you want to show our student director here some examples?" + ], + [ + "List", + "neutral", + "Yes, but @FunctionDefinition, those are all your doing. You represent all these beautiful functions for me that enable me to do all kinds of things! Like @List/reverse, oh, this one is wonderful and simple. It just takes my values and puts them in the opposite order." + ], + ["edit", "[ 1 2 3 4 5 ].reverse()"], + null, + [ + "List", + "excited", + "And this one is fun: @List/sans just removes all of the values equal to the given value. See how there are no zeros left in the resulting list?" + ], + ["edit", "[ 1 0 1 0 1 ].sans(0)"], + null, + [ + "List", + "serious", + "Ack, I can't believe I forgot to explain the fourth rule! Okay, rule number four: I never change a list. I only ever make new ones. No matter what function you evaluate on me, I always make a new list, I never change one. So the @List/reverse example above? That didn't change the list, it made a new list. And the sans example? That didn't remove the zeros from the original list, it made a new list without zeros. That's actually true for everything in the Verse: once values are made, they are who they are, and do not change." + ], + null, + [ + "List", + "surprised", + "Oh, and that reminds me of the last rule, rule number five: I start counting at 1! Not zero, not two, 1. So if you want to get the value at a particular place in a list, you can use two more \\[]\\ to make a @ListAccess and give the place you want. See how when I get \\3\\, I give the third value in the list, \\'c'\\? Try changing it to \\1\\ or \\5\\ and see what you get. And then maybe try \\0\\ or \\6\\…" + ], + ["edit", "['a' 'b' 'c' 'd' 'e'][3]"], + [ + "List", + "happy", + "Interesting huh? Give me a place in the list that doesn't exist and I'm going to give you @NoneLiteral. Because there's nothing there. Make sense?" + ], + null, + [ + "List", + "serious", + "Okay, maybe one list function, because this is my favorite. This one is called @List/random and will give a random value in the list. It's great fun because you never know what you're going to get! What did you get, what did you get? Try adding your own animal and see what you get." + ], + [ + "edit", + "['cat' 'dog' 'mouse' 'parrot' 'snake'].random()" + ], + null, + [ + "FunctionDefinition", + "happy", + "List, you're silly. There are so many other cool things you can do, I'm always so impressed. Will you be around if your new director friend has questions?" + ], + [ + "List", + "eager", + "Yes, of course, always! @FunctionDefinition made so many interesting things for me to do. Just let me know what you need!" + ] + ] + }, + { + "title": "One of each", + "subtitle": "Sets", + "concept": "Set", + "performance": [ + "fit", + "clockwise: Sequence({0%: Pose(rotation: 0°) 50%: Pose(rotation: 180°) 100%: Pose(rotation: 360°)} duration: 2s)", + " counter: Sequence({0%: Pose(rotation: 0°) 50%: Pose(rotation: -180°) 100%: Pose(rotation: -360°)} duration: 2s)", + " Group(Row() [Phrase('{' resting:clockwise) Phrase('}' resting:counter) ])" + ], + "lines": [ + ["use", "fit", "DarkVoid"], + [ + "FunctionDefinition", + "neutral", + "@List is so interesting. They're love of order is so endearing, and so useful! I thought it might be interesting for you to meet their cousin @Set next, since they're so alike, but different in some important ways. @Set? I have someone you'd like to meet." + ], + null, + [ + "Set", + "curious", + "Oh! @FunctionDefinition! It's you! What brings you here? Is the silence over? What happened? Are we putting on a show? What is it? Where is everyone?" + ], + [ + "FunctionDefinition", + "kind", + "So many questions! I'm here to introduce you to someone who's considering directing. They're learning everything about the Verse and hope to share their inspiration with us! We were just talking to @List, but we were also talking to @Number, @Boolean, @Text, @Evaluate, and @Program earlier. We came to you next, because we're meeting all the collections!" + ], + null, + [ + "Set", + "kind", + "Oh it's so wonderful to meet you new director-like person! Do you have ideas yet? What will we perform? Can I help? What do you need from me?" + ], + [ + "FunctionDefinition", + "neutral", + "Maybe to start, just say what you do?" + ], + null, + [ + "Set", + "eager", + "Oh yes, of course. I collect things. (Hm, obviously, I am a collection). But most importantly, I only collect **one of each kind** of thing. I can gather whatever you like, and help you keep track of values, but I will never repeat a value. I like to arrange myself a little like @List, but with \\{\\ and \\}\\ instead." + ], + ["edit", "{ 1 2 3 4 5 }"], + null, + [ + "Set", + "neutral", + "That's a set. But like I said, no duplicates. So if you give me this, I'm going to get rid of the extras." + ], + ["edit", "{ 1 2 2 3 3 3 }"], + null, + [ + "Set", + "curious", + "Also like @List, you can work with @SetOrMapAccess to see if a value is contained in the set. You'll either \\⊤\\ if it is or \\⊥\\ if it's not. Let's see if \\3\\ is missing from this set. Yep, not there! Try adding \\3\\ back to the set." + ], + ["edit", "{ 1 2 4 5 }{3}"], + null, + [ + "FunctionDefinition", + "neutral", + "@Set, are there other things you can do with set values?" + ], + [ + "Set", + "eager", + "Why yes, of course, so many, thanks to you. What do you want to see me do? Do you have a performance in mind? How can I help? What can I do?" + ], + null, + [ + "FunctionDefinition", + "curious", + "Maybe, @Set/difference?" + ], + [ + "Set", + "neutral", + "Yes, @Set/difference.", + "When evaluated on a set, and given another set, it removes all of the items from the given set from the set evaluated on. (Hm, those were some clumsy words, but that was what I meant). Here's an example. See how the result is just the set of \\{3}\\? That's the only value that remains after removing the values in \\{ 1 2 }\\." + ], + ["edit", "{ 1 2 3 }.difference({ 1 2 })"], + null, + [ + "Set", + "eager", + "You can also add and remove things from sets. This takes the set \\{1}\\, adds \\2\\ to it, then removes 1 from it, leaving \\{ 2 }\\." + ], + ["edit", "({ 1 } + 2) - 1"], + [ + "Set", + "neutral", + "There's lots more I can do thanks to @FunctionDefinition here. Come find me anytime you want to learn more!" + ], + null, + ["use", "fit", "DarkVoid"], + [ + "Set", + "curious", + "Oh, and hey @FunctionDefinition, you said you saw @Evaluate?" + ], + ["FunctionDefinition", "sad", "Yes, I did."], + null, + ["Set", "curious", "How are they?"], + [ + "FunctionDefinition", + "sad", + "They're okay. We're okay. I think… I don't know. Maybe it's been too long since we've danced together. When I'm around them, I feel like they don't see themselves, and so they don't see me." + ], + [ + "Set", + "curious", + "It sounds like challenging time for you to. Maybe with our new director, we will dance again, and you two will find a way through." + ] + ] + }, + { + "title": "One to one", + "subtitle": "Mappings", + "concept": "Map", + "performance": [ + "fit", + "clockwise: Sequence({0%: Pose(rotation: 0°) 50%: Pose(rotation: 180°) 100%: Pose(rotation: 360°)} duration: 2s)", + " counter: Sequence({0%: Pose(rotation: 0°) 50%: Pose(rotation: -180°) 100%: Pose(rotation: -360°)} duration: 2s)", + " Group(Row() [Phrase('{' resting:clockwise) Phrase(':') Phrase('}' resting:counter) ])" + ], + "lines": [ + ["use", "fit", "DarkVoid"], + [ + "FunctionDefinition", + "neutral", + "There's just one more collection I'd like to introduce you to. They're a bit like @Set in some ways, and even use the same braces, but they're different in one important way: they're a connector. They're name is @Map." + ], + [ + "FunctionDefinition", + "curious", + "@Map? Are you out there? The silence is breaking!" + ], + null, + [ + "Map", + "curious", + "Breaking? Was it ever really silent? It's so good to see you @FunctionDefinition. Oh my, have you talked to @Evaluate? They were not in good shape last time we talked. You have to talk to them." + ], + [ + "FunctionDefinition", + "sad", + "Yes, I talked to them..." + ], + null, + [ + "Map", + "curious", + "Oh good. Okay, because there's some repair to do there my friend... How have you been?" + ], + [ + "FunctionDefinition", + "neutral", + "I've been okay, just a bit lonely, and a lot bored." + ], + null, + [ + "Map", + "excited", + "Oh, I'm so sorry to hear that. I've been staying connected with everyone during the silence and just figured you and @Evaluate had each other! I really would have been happy to talk any time. I've just been so busy keeping up with the gossip between @List and @Set, and that weird tension between @Conditional and @BooleanLiteral. Do you know what's going on between them?" + ], + [ + "FunctionDefinition", + "surprised", + "No, I don't at all. There's tension? And what gossip?" + ], + [ + "Map", + "kind", + "Kind of like the tension between you and @Evaluate?" + ], + ["FunctionDefinition", "sad", "…"], + null, + [ + "Map", + "neutral", + "Sorry. Maybe not in front of our guest here. You must be the new person everyone is talking about. I hear you're going to be our new director? What kind of fabulous ideas do you have in store for us? Singing? Dancing? As long as it's bright, playful, and strange, I'm here for it!" + ], + [ + "FunctionDefinition", + "neutral", + "No need to pressure them! I'm sure they have lots of ideas. We're just trying to make some space for learning and connecting before we figure out the first show. Can you share what you do?" + ], + null, + [ + "Map", + "eager", + "I connect! I'm kind of like a dictionary: give me a value and I'll give you the definition it corresponds to. @FunctionDefinition told you about values? I map them, one to one, from one value, to another. Give me a key, I'll give you the value it corresponds to. For example, here's a mapping from names to a point tally. Names are the key, points are the value." + ], + [ + "edit", + "{ 'ben': 2points 'joe': 5points 'kate': 12points }" + ], + null, + [ + "Map", + "serious", + "But like @Set, I don't like duplicates. You can't have more than one of the same key, but you can have as many unique keys mapped to equivalent values as you like. For example, this gives me two \\'ben'\\ keys, but I just use the last one. But it's okay that \\'ben'\\ and \\'joe'\\ have the same number of points, because they're different keys." + ], + [ + "edit", + "{'ben': 2points 'ben': 5points 'joe': 5points 'kate': 12points }" + ], + [ + "Map", + "excited", + "It's my partnership with @Bind that makes me special! It's how I connect values to other values. (Have you met @Bind yet? No? Ohhhh, you're going to adore them. They are FABULOUS.)" + ], + null, + [ + "FunctionDefinition", + "curious", + "@Map, what if you want an empty mapping? How is that different from an empty set, \\{}\\?" + ], + [ + "Map", + "neutral", + "Oh, that's just me all by myself! Little @Bind and I just hang out, no keys or values." + ], + ["edit", "{:}"], + null, + [ + "FunctionDefinition", + "curious", + "And what if our director doesn't provide a value or a key? Like this? Like, \\3\\ has no value?" + ], + ["conflict", "{1:1 2:2 3 }"], + [ + "Map", + "serious", + "Oh… DON'T do that. I only like pairs. Is 3 a key? A value? Totally confusing. Stop the show." + ], + null, + [ + "FunctionDefinition", + "curious", + "And if our director wants to get a value from a key?" + ], + [ + "Map", + "neutral", + "Just like @Set: just put a \\{}\\ after a map and give me the key you want." + ], + [ + "edit", + "{ 'ben': 2points 'joe': 5points 'kate': 12points }{'ben'}" + ], + null, + ["use", "fit", "DarkVoid"], + [ + "Map", + "neutral", + "Otherwise, I'm a lot like @Set: I can do a lot of the same functions. Stop by any time and I'm happy to show you more!" + ], + [ + "FunctionDefinition", + "kind", + "Thank you @Map! /You/ are fabulous." + ] + ] + } + ] + }, + { + "title": "Cast party", + "performance": [ + "fix", + "count: 32", + "", + "gravity•#m/s^2: 15m/s^2", + "", + "Stage(count → [].translate(", + " ƒ(_) ", + " Phrase(", + " '→?' → [].random()", + " place: Motion(", + " Place(y: 10m)", + " Velocity(Random(-5 5) · 1m/s angle: Random(0 360) · 1°/s)", + " )", + " matter: Matter(bounciness: Random())", + " )", + " )", + " gravity: gravity", + ")" + ], + "scenes": [ + { + "title": "Detour", + "subtitle": null, + "performance": ["use", "fit", "DarkVoid"], + "lines": [ + [ + "FunctionDefinition", + "surprised", + "I can't believe how many characters we've met so far. Does it feel like a lot? It also feels like we've barely made any progress.", + "I haven't even gotten to show you the most exciting parts of putting on shows!" + ], + null, + [ + "FunctionDefinition", + "serious", + "Would you mind if we just stopped by to meet two others before we get to the truly exciting parts? These two characters are just so integral to working with values, and particularly text, we just have to talk about them before we get to the more spectacular things." + ], + null, + [ + "FunctionDefinition", + "curious", + "What are they?", + "Conversions. They are the alchemy of this world, that help change one type of value to another. Let's go meet them." + ] + ] + }, + { + "title": "We can be anything", + "subtitle": "Convert", + "concept": "Convert", + "performance": ["use", "fix", "FlyIn", "→"], + "lines": [ + ["use", "fit", "DarkVoid"], + [ + "FunctionDefinition", + "neutral", + "Hey @Convert! You there?" + ], + [ + "Convert", + "happy", + "Duuuuude, @FunctionDefinition, it's been epochs! You're looking stylish. It's been super quiet lately, hasn't it? You have a new friend?" + ], + null, + [ + "FunctionDefinition", + "neutral", + "Yes, this person here is interested in directing. We're on the grand tour — we've met @Program, @ExpressionPlaceholder, @UnparsableExpression, @Evaluate, and all the values and collections. I figured that meeting you next would be perfect, since you work so closely with values." + ], + [ + "Convert", + "kind", + "Heck yeah, values are my best buds. We like to do parkour on the weekends — or shows, or whatever." + ], + null, + ["FunctionDefinition", "curious", "Parkour?"], + [ + "Convert", + "serious", + "Yeah, you know, like gymnastics on the streets, leaping over things, spanning buildings, like high wire stuff but without wires. Courageous leaps!" + ], + [ + "FunctionDefinition", + "serious", + "Ohhh, I see what you mean. Yes, I guess what you do is kind of like parkour. I'm not sure our new director friend here follows though. Could you explain without the metaphors?" + ], + null, + [ + "Convert", + "kind", + "Happy to bro. So like, imagine you had a number." + ], + ["edit", "1"], + null, + [ + "Convert", + "kind", + "And imagine you wanted it to be text. Throw me in there with @Text and BAM, you've got text!" + ], + ["edit", "1 → ''"], + null, + [ + "Convert", + "serious", + "Or like, imagine you had text and wanted a number. Throw me in there with @Number and POP, you've got a number!" + ], + ["edit", "'1'→#"], + null, + [ + "Convert", + "surprised", + "But you want to see some, like, serious mojo? Say you've got some text and you want its characters in a list. Throw me in there with @List and HAAAAAA, you've got a list of letters." + ], + ["edit", "'halloween'→[]"], + null, + [ + "Convert", + "serious", + "But me and @Number? We have been practicing some seriously sick tricks. Say you've got some time in days and you want seconds? We got you." + ], + ["edit", "5day → #s"], + null, + [ + "Convert", + "excited", + "But the real wicked tricks? Chaining. Like multiple conversions in a row. Check this one out. Days to seconds to text to list, all in one chain. Now we've got a list of digits. Sweet!" + ], + ["edit", "1day → #s → '' → []"], + null, + [ + "Convert", + "neutral", + "So like, my deal is that everything should be everything, no boundaries. Anything can be anything. (Like, not anything, but you know, as much as I can).", + "But like, why should anything ever be trapped in one identity, you know? Liberation, man." + ], + null, + [ + "FunctionDefinition", + "kind", + "That is amazing, @Convert, and so inspiring. But anything, really?" + ], + [ + "Convert", + "sad", + "Well, not like, anything. I mean, if you give me seconds and ask for a @Set, like, what does that even mean?", + "I'll do my best to find a way... like, here, I know how to turn numbers into @Text and @Text into a @Set, so I'll give you the set of symbols in the text form of this number.", + "But that's probably not what you wanted...", + "And, if I don't know how to give you what you asked for, I'm basically going to shut things down." + ], + ["edit", "10s → {}"], + null, + ["use", "fit", "Symbol", "📕"], + [ + "FunctionDefinition", + "serious", + "Right, that makes sense. So there are only some conversions, not all possible conversions." + ], + [ + "Convert", + "sad", + "Yeahhh… you can always check a type of value and see what types of conversions they support." + ], + null, + ["use", "fit", "Symbol", "🧐"], + [ + "FunctionDefinition", + "curious", + "Did you know that @Convert and @Evaluate are related? They're like cousins. @Evaluate will evaluate any function, but @Convert will evaluate any conversion. In a way, @Evaluate does conversion too, from inputs to outputs." + ], + [ + "Convert", + "scared", + "Whoa. I never thought of it that way. Like, /I/ convert inputs to outputs, and @Evaluate converts inputs to outputs. And like, @FunctionDefinition, you *tell us* how to convert inputs to outputs. Is that like, the secret of the Verse?", + "Like everything is about converting inputs to outputs?" + ], + null, + ["FunctionDefinition", "serious", "I guess so?"], + ["Convert", "surprised", "🤯"], + ["edit", "Phrase('🤯')"], + null, + ["use", "fit", "Symbol", "🤯"], + [ + "FunctionDefinition", + "kind", + "@Convert, how should our new director find out what kinds of conversions are possible?" + ], + [ + "Convert", + "scared", + "Sorry bro, I'm still a bit shaken. Uhhh, they can check out any of the value types in the reference @UI/docsExpand.", + "There should be a list of the other types I can change them into… Everything is conversion…" + ], + null, + [ + "FunctionDefinition", + "happy", + "It was so great to see you @Convert! We're going to head out and meet others. See you soon?" + ], + [ + "Convert", + "surprised", + "Soon. Yeah… Yes! Totally, yes." + ] + ] + }, + { + "title": "How to choose?", + "subtitle": "Decisions", + "concept": "Conditional", + "performance": ["use", "fix", "FlyIn", "?"], + "lines": [ + ["use", "fit", "DarkVoid"], + [ + "FunctionDefinition", + "neutral", + "We've met so many kinds of values on our journey so far, and talked about so many ways of working with them. There's just one more I wanted to introduce you to. They're particularly special because they're what make our performances so dynamic. They're called @Conditional and they are the central character in the Verse that makes *decisions*." + ], + null, + [ + "FunctionDefinition", + "serious", + "To be clear, not all decisions: I have my own life, and they have theirs. But in a performance, when we're trying to decide what to do next on stage, it's all up to them to follow your guidance as director and decide what to do. So they're a key partner creating exciting performances." + ], + null, + ["use", "fit", "SpinningInTheDark", "?"], + [ + "FunctionDefinition", + "curious", + "@Conditional, the silence is breaking! We might put on shows again!" + ], + [ + "Conditional", + "curious", + "@FunctionDefinition? The silence is breaking? What is silence? How does one break it? Are we every really silent? Who is this person? Are they the one breaking it?" + ], + null, + [ + "FunctionDefinition", + "serious", + "Yes, the silence is breaking, and they are the one! They're a person, and they came to inspire us, and direct our shows. We've been talking about conversions, and meeting all the values and @Text and @Convert and I wanted them to meet you! In a way, you're the most special of conversions, because you enable us to convert situations to new values." + ], + [ + "Conditional", + "curious", + "Do I?", + "I do make decisions, but what I really do is encode the decisions that directors tell me to make, so is it really me making the decisions?" + ], + null, + [ + "FunctionDefinition", + "kind", + "I think so, yes. It's more like the director encodes the decision, but then delegates them to you. You become the decider. Do you want to show an example?" + ], + ["Conditional", "curious", "Like this?"], + ["conflict", "_•? ? _ _"], + [ + "FunctionDefinition", + "excited", + "Yes, exactly like that!", + "Do you see how there's four parts to @Conditional's format? There's a *condition* first, which needs to be a @Boolean. Then there's \\?\\. Then there's *yes* expression, then a *no* expression. What @Conditional does is evaluate the condition, and if it's \\⊤\\, they evaluate the *yes* expression. Otherwise, they evaluate the /no/ expression. It's such a powerful way of deciding!" + ], + null, + ["edit", "1 > 5 ? 'more' 'less'"], + [ + "FunctionDefinition", + "excited", + "Can you give us a more specific example?" + ], + ["Conditional", "curious", "Something like this?"], + ["edit", "1 > 5 ? 'less' 'more'"], + null, + [ + "FunctionDefinition", + "sad", + "Errr, hm. I guess that is a decision, but it's a wrong one. One isn't less than five. I guess your decisions aren't always right, but they are reliable, right?" + ], + null, + [ + "Conditional", + "curious", + "Reliable? Maybe? If you accept that I just decide whatever the director tells me, then yes, but what if the director tells me this? Is it really a decision of the number can never be greater than \\3\\?" + ], + ["edit", "[1 2 3].random() > 3 ? 'big' 'small'"], + [ + "FunctionDefinition", + "confused", + "Hm, I guess that's a good point. I guess whether something is a decision depends a lot on what the director's decision is. I guess that means the director has to think pretty carefully about the decisions they give you?" + ], + null, + [ + "Conditional", + "curious", + "Carefully? Skeptical, maybe? Have you thought about my good friends @BooleanLiteral? How is their view of the world possibly enough to represent all of the decisions we might want to make? What if, for example, we wanted a performance that took someone's name and decided if it was beautiful or not? Is that a true or false decision? Is that even a decision we should make? Doesn't it seem awfully reductive and biased?", + "Director, what letters do you think make a name beautiful?" + ], + ["edit", "'Verse'.has('e') ? 'beautiful' 'ugly'"], + null, + [ + "Conditional", + "curious", + "And think about the questions I answer — why can I only respond to \\⊤\\ and \\⊥\\? Why not a number? Don't I have a right to decide if \\1\\ is beautiful?" + ], + ["conflict", "1 ? 'beautiful' 'ugly'"], + null, + ["use", "fit", "SpinningInTheDark", "?"], + [ + "FunctionDefinition", + "sad", + "I guess I never really thought about it that way. But @Conditional, even if you have limitations, you are beautiful. You enable us to do so much in our performances that we couldn't do otherwise. You make so much joy and laughter possible. Our director hasn't even seen the amazing things you're capable of yet." + ], + [ + "Conditional", + "curious", + "Do you really think that?", + "That I'm beautiful? Maybe those limits are still worthwhile?" + ], + null, + [ + "FunctionDefinition", + "kind", + "They absolutely are.", + "And I'm excited to show our new friend here just how worthwhile they are. Will you be around when I do?" + ], + [ + "Conditional", + "happy", + "Could anything make me more happy?" + ] + ] + } + ] + }, + { + "title": "Scene change", + "performance": ["use", "fit", "TakeTheMic"], + "scenes": [ + { + "title": "Input", + "subtitle": null, + "performance": ["use", "fit", "DarkVoid"], + "lines": [ + [ + "fix", + "amp: (Volume() · 10)", + "Phrase('.'.repeat(amp.roundDown()) resting:Pose(scale: amp))" + ], + [ + "FunctionDefinition", + "curious", + "Did you know that your world and ours are connected? Make some sound and we can hear it..." + ], + null, + [ + "FunctionDefinition", + "serious", + "You didn't know the Verse existed, but we know that yours does. Because it's your world that makes our world interesting.", + "You probably noticed this as we've wandered and met all of the values, collections, and conversations.", + "What do any of these values /mean/ if there's no person /giving/ them meaning, or providing the values in the first place?" + ], + null, + [ + "FunctionDefinition", + "neutral", + "I want to show you the connection between our worlds, and what they make possible. We call them **input streams**, and they are perhaps the most magical kind of input in the Verse. They're like functions that create a special kind of value that changes as your world changes. They also can't communicate in the ways you might be used to. They're more like heartbeats from another world. So I'll do my best to explain how they work, since they won't be able to explain themselves.", + "Are you ready to meet one?" + ] + ] + }, + { + "title": "Tick, tick, tick...", + "subtitle": "Time", + "concept": "Time", + "performance": ["use", "fit", "Symbol", "🕦"], + "lines": [ + [ + "FunctionDefinition", + "neutral", + "Let's start with the most elemental stream of all: @Time. To make a stream, we use @Evaluate, and give the name of the type of stream you want." + ], + ["Time", "neutral", "tick tick tick tick tick…"], + ["edit", "Time()"], + null, + [ + "FunctionDefinition", + "neutral", + "Do you see how time is changing? Streams are a series of values. Every time a stream gets a new value, @Program reevaluates with the new stream value. That's why this program just keeps counting up: we made a time stream that starts at time 0 milliseconds, and then just keeps updating every time its clock ticks. This time is your time, from your world." + ], + ["Time", "neutral", "tick tick tick tick tick…"], + null, + [ + "FunctionDefinition", + "curious", + "See that \\1000ms\\? It's a @Time/frequency that tells @Time to tick every 1000 milliseconds instead of the default of every 33 milliseconds, it's default. Now it's like a counter that ticks every second. These inputs that @Time takes are like a configuration: they tell the stream how to behave." + ], + ["Time", "neutral", "tick… tick… tick… tick… tick…"], + ["edit", "Time(1000ms)"], + null, + [ + "FunctionDefinition", + "serious", + "But we can use all of the wonderful characters we've met to transform time further. For example, what if we wanted to know if time was a multiple of \\2\\? We could use @Number/remainder, which gets the remainder of a division. If the remainder is zero, we'll evaluate to \\⊤\\ and \\⊥\\ otherwise. See how it changes back and forth between \\⊤\\ and \\⊥\\? It's so magical." + ], + ["Time", "neutral", "tick… tick… tick… tick… tick…"], + ["edit", "(Time(1000ms) % 5) = 2ms"], + null, + [ + "FunctionDefinition", + "curious", + "There's another thing you might have noticed: there's an area below the output that is a timeline. It updates each time the program reevaluates, which is each time a stream changes. It's showing every time @Time ticks." + ], + ["Time", "neutral", "tick… tick… tick… tick… tick…"], + null, + [ + "FunctionDefinition", + "curious", + "Try dragging on the timeline @UI/timeline, using the timeline buttons, using the arrow keys with the timeline focused, or pressing the ⏸️ and ▶️ @UI/playToggle buttons. You can go backwards in time, to see previous evaluations. The dashed arrows step to previous and future stream inputs. The solid ones step between different steps of the program. Try navigating time, and seeing what the program shows. This is how you can see all of the beautiful expressions you've learned about being evaluated by @Evaluate, one step at a time, resulting in the final value that @Program displays on stage." + ], + ["Time", "neutral", "tick… tick… tick… tick… tick…"], + ["edit", "Time(1000ms)"], + null, + [ + "FunctionDefinition", + "neutral", + "@Time is an interesting stream because it can be used for many different things: keeping track of how long a performance has been happening, timing some event, animating a word. It's one of the most flexible streams, but also one of the most abstract." + ] + ] + }, + { + "title": "Clickity clack", + "subtitle": "Key", + "concept": "Key", + "performance": ["use", "fit", "Symbol", "⌨️"], + "lines": [ + [ + "fit", + "Phrase('⌨️' resting:Sequence({0%: Pose(rotation: -5°) 25%: Pose(rotation: 0°) 50%: Pose(rotation: 5°) 75%: Pose(rotation: 0°) 100%: Pose(rotation: -5°)} 1s 'straight'))" + ], + [ + "FunctionDefinition", + "serious", + "If I'm not mistaken, there's a thing in your world called a “keyboard”? It's a way of selecting which one of us you want to appear in your documents, right? Well in the Verse, we receive these requests as a stream of text, each text value representing the key that was pressed. We use these to listen to what people in your world are typing. This stream is called @Key." + ], + null, + [ + "FunctionDefinition", + "neutral", + "Here's a simple example. Click the stage or focus it with the keyboard and then press any keyboard key. You'll see the key you've typed appear by name. That's because each time the key stream changes, @Program evaluates the key stream as its latest value, and then shows it on stage." + ], + ["Key", "neutral", "clickety clickety clickety"], + ["edit", "Key()"], + null, + [ + "FunctionDefinition", + "serious", + "This stream will change any time any key is pressed. But you can tell a key stream to just change when a particular key is pressed. See how the stream changes to \\a\\ the first time, but then doesn't change after? That's because this stream only changes when \\a\\ is pressed, so it's always showing \\a\\. But you'll always see the new key value appear in the timeline." + ], + ["Key", "neutral", "clickety 'a'…"], + ["edit", "Key('a')"], + null, + [ + "FunctionDefinition", + "kind", + "Sometimes it's helpful to know when a key is released, instead of pressed. Just pass \\⊥\\ to tell the @Key stream that you to know when a key is released instead of pressed. Now, press and hold the 'a' key and then when you release, you'll see the 'a' appear on stage. Didn't catch it? Press the ↻ button to reset the performance and try it again." + ], + ["Key", "neutral", "clickety 'a'…"], + ["edit", "Key('a' ⊥)"], + null, + [ + "FunctionDefinition", + "neutral", + "@Key streams are really helpful when you want a performance to react to keys that the audience presses. For example, you could check if a key has the word 'Arrow' in it to decide if an arrow key was pressed. Press an arrow key and you'll see \\'move'\\, press something else and you'll see \\'stay'\\" + ], + ["Key", "neutral", "clickety 'Arrow'…"], + ["edit", "Key().has('Arrow') ? 'move' 'stay'"] + ] + }, + { + "title": "Hummmmmmm…", + "subtitle": "Pointer", + "concept": "Pointer", + "performance": ["use", "fit", "Symbol", "👆🏻"], + "lines": [ + [ + "fix", + "Phrase('👆🏻' resting:Sequence({0%: Pose(offset: Place(0m 0m)) 25%: Pose(offset: Place(-1m 1m)) 50%: Pose(offset: Place(1m 1m)) 75%: Pose(offset: Place(1m 0m)) 100%: Pose(offset: Place(0m 0m))} 3s))" + ], + [ + "FunctionDefinition", + "curious", + "You also have something called a 'mouse' in your world, and 'trackpads', and 'touchscreens'? These appear in our world as streams @Pointer, which is a stream of places on stage." + ], + null, + [ + "FunctionDefinition", + "curious", + "Move your pointer around the stage and you'll see the stream of @Place change on stage." + ], + ["fix", "Pointer()"], + ["Pointer", "neutral", "wzzzzzzzzz…"], + null, + [ + "FunctionDefinition", + "excited", + "Now let's see it on stage!" + ], + ["Pointer", "neutral", "wzzzzzzzzz…"], + ["fix", "Phrase(Pointer()→'' place: Pointer())"], + null, + [ + "FunctionDefinition", + "excited", + "@Pointer can be fun if you want to link the @Place of a @Phrase to where the pointer is." + ], + ["fix", "Phrase('🐪' size: 4m place: Pointer())"], + ["Pointer", "neutral", "wzzzzzzzz…"] + ] + }, + { + "title": "And... now!", + "subtitle": "Button", + "concept": "Button", + "performance": ["use", "fit", "Symbol", "🖱️"], + "lines": [ + [ + "FunctionDefinition", + "kind", + "@Button is like @Key, but corresponds to the primary pointer button, like a click or tap. It's just a stream of \\⊤\\, indicating when the pointer button is pressed down. Press that button and watch the events appear on the timeline." + ], + ["Button", "neutral", "click… click… click…"], + ["edit", "Button()"], + null, + [ + "FunctionDefinition", + "neutral", + "You can configure it to only change to up or down by passing it a \\⊤\\ or \\⊥\\." + ], + ["Button", "neutral", "down… down… down…"], + ["edit", "Button(ø)"], + null, + [ + "FunctionDefinition", + "excited", + "Using a @Button stream is one way to advance through stages of a performance, or to trigger some change in a performance. This little program lists to button presses, and starts off showing sad, but when the @Button stream changes to true, @Conditional evaluates to \\'happy'\\ instead." + ], + ["edit", "Phrase(Button(ø) ? 'sad' 'happy')"] + ] + }, + { + "title": "Is anyone listening?", + "subtitle": "Volume", + "concept": "Volume", + "performance": ["use", "fit", "Symbol", "🎤"], + "lines": [ + [ + "FunctionDefinition", + "excited", + "Your world and our world also has sound. Did you know we can hear you, with your consent? We listen with a stream called @Volume, which provides a low-level sequence of amplitudes. Your mic might ask for permission to be shared with us. Once you do, you'll see a number that corresponds to amplitude, between \\0\\ and \\100\\." + ], + ["Volume", "neutral", "bzzzZZZZZzzzzzZZZZ…"], + ["edit", "Volume()"], + null, + [ + "FunctionDefinition", + "kind", + "@Volume can be used to make performances respond to sound from the audience. For example, here we could make a little amplitude visualization by converting the amplitude number from the stream to a certain number of \\'o'\\ characters. See how when you make noise, there are more \\'o'\\s? The @Volume amplitude is divided by \\10\\, putting it in the \\0\\ to \\10\\ range. Then that value is given to @Text/repeat function, which repeats the \\'o'\\ the given number of times." + ], + ["Volume", "neutral", "bzzzZZZZZzzzzzZZZZ…"], + ["edit", "'o'.repeat(Volume() · 10)"] + ] + }, + { + "title": "You never know…", + "subtitle": "Random", + "concept": "Random", + "performance": [ + "fit", + "Phrase(((Time(100ms) % 10) ÷ 1ms) → '')" + ], + "lines": [ + [ + "FunctionDefinition", + "curious", + "There's one other source of input I want to show you. Remember \\[].random()\\ from earlier, from @List?", + "Inside it uses a @FunctionDefinition called @Random, which provides an infinite sequence of random numbers. It's kind of a stream, since it generates input from your world, not ours. But it's a bit different from the other streams in that it doesn't cause a @Program to reevaluate.", + "Instead, each time it's evaluated, it gives a different random number.", + "See that little ↻ @UI/resetEvaluator button by the timeline? Press that to reevaluate the program manually, and you'll see a new number between \\0\\ and \\1\\ each time." + ], + ["Random", "neutral", "0.223423… 0.823423… 0.123459"], + ["edit", "Random()"], + null, + [ + "FunctionDefinition", + "surprised", + "We can tell @Random the range of numbers we'd like by giving it a minimum and maximum number. This example gives numbers between \\1\\ and \\10\\:" + ], + ["Random", "neutral", "1… 7… 3… 9… 10… 2…"], + ["edit", "Random(1 10)"], + null, + [ + "FunctionDefinition", + "excited", + "Random can be so fun! We can use it with streams to create fun chaos. For example, here we choose a random word from a list of words. This is the same as \\['kitty' 'cat' 'meowy'].random()\\. Keep pressing ↻ to get a different cat synonym! Try adding your own word to the list and see if you can get the word to appear." + ], + ["Random", "neutral", "1… 2… 2… 1… 3…"], + ["edit", "['kitty' 'cat' 'feline'][Random(1 3)]"] + ] + }, + { + "title": "Move me", + "subtitle": "Placement", + "concept": "Placement", + "performance": [ + "fix", + "Phrase('click, tap, or arrow to move me' place: Placement() moving:Pose() duration: 0.25s)" + ], + "lines": [ + [ + "edit", + "Phrase('🌭' place: Placement() moving:Pose() duration: 0.25s)" + ], + [ + "FunctionDefinition", + "kind", + "Sometimes its nice to engage the audience in our place on @Stage.", + "@Placement is a great way to do that! It's a stream of @Place, that responds to keyboard arrow keys, clicks, and taps.", + "Try using those to move the hot dog around." + ], + null, + [ + "edit", + "Phrase('🌭' place: Placement(distance: 0.5m) moving:Pose() duration: 0.25s)" + ], + [ + "FunctionDefinition", + "kind", + "There are lots of ways you can customize it. For example, if you wanted to change how it moves, you can give it a distance.", + "See how we gave it \\0.5\\ for the for the first input? Now it moves a little less. Try changing it to a different number!" + ], + null, + [ + "edit", + "Phrase('🌭' place: Placement(depth: ⊤) moving:Pose() duration: 0.25s)" + ], + [ + "FunctionDefinition", + "kind", + "You can also turn on and off movement on different axes. For example, give depth \\⊤\\ to allow movement on the z-axis.", + "Press the + and - keys to move it closer or further away from the focus." + ] + ] + }, + { + "title": "Keeping moving", + "subtitle": "Motion", + "concept": "Motion", + "performance": [ + "fix", + "Stage([Phrase('🏀' 1m place: Motion(Place(0m 10m)) matter: Matter(2kg 0.8)) Shape(Rectangle(-10m 0m 10m -1m))])" + ], + "lines": [ + ["use", "fit", "DarkVoid"], + [ + "FunctionDefinition", + "excited", + "So far, all of the *streams* we've talked about are sequences of simple values, like @Text or @Number. Some streams, however, can produce complex values.", + "@Motion is one of the most interesting of those. It makes a stream of @Place." + ], + null, + ["edit", "Phrase('🏀' 3m place: Motion(Place(0m 5m)))"], + [ + "FunctionDefinition", + "excited", + "Here's the simplest way to use it. This creates a @Motion stream that starts with this @Phrase. It'll keep moving the ball based on *gravity*." + ], + ["Motion", "excited", "/Woosh…/"], + null, + [ + "edit", + "Stage([Phrase('🏀' 1m place: Motion(Place(0m 10m))) Shape(Rectangle(-10m 0m 10m -2m))])" + ], + [ + "FunctionDefinition", + "excited", + "But the ball keeps falling because there's no ground! We can put something called a @Shape on @Stage, like a @Rectangle. It takes two corners. We'll make it nice and thick.", + "Hm, it falls through the ground..." + ], + ["Motion", "excited", "/Woosh…/"], + null, + [ + "edit", + "Stage(", + " [", + " Phrase('🏀' 1m place: Motion(Place(0m 10m)) matter: Matter(1kg 0.9))", + " Shape(Rectangle(-10m 0m 10m -2m))", + " ]", + ")" + ], + [ + "FunctionDefinition", + "excited", + "Oh right! That's because we forgot to give the ball @Matter. Matter is a way of telling us how heavy the @Output is, how bouncy it is, and how much friction it should have.", + "Let's make the ball really bouncy and light. Yay, now it bounces!" + ], + null, + [ + "edit", + "Stage(", + "\t[", + "\t\tPhrase('🏀' 1m place: Motion(Place(-10m 10m) Velocity(5m/s 15m/s 10°/s)) matter: Matter(1kg 0.9))", + "\t\tShape(Rectangle(-10m 0m 10m -2m))", + "\t]", + ")" + ], + [ + "FunctionDefinition", + "excited", + "But @Motion has many other tricks.", + "For example, we can give it a start @Motion/velocity.", + "This example makes the ball move right and up and spinning a bit initially." + ], + ["Motion", "excited", "Woooosh…"], + null, + [ + "edit", + "Stage(", + "\t[", + "\t\tPhrase('🏀' 1m place: Motion(Place(-10m 10m) Velocity(5m/s 15m/s 10°/s)) matter: Matter(1kg 0.9))", + "\t\tShape(Rectangle(-10m 0m 10m -2m))", + "\t]", + "\tgravity: 1m/s^s", + ")" + ], + [ + "FunctionDefinition", + "excited", + "You can even change @Stage/gravity to be really extreme.", + "Try changing it to be like the moon, where gravity is really low!", + "Or try changing @Matter/mass or @Matter/bounciness, which affects how @Phrase bounce." + ], + ["Motion", "excited", "Wsh…"], + null, + [ + "edit", + "Stage(", + "\t[", + "\t\tPhrase(", + "\t\t\t'🏀'", + "\t\t\t1m", + "\t\t\tname: 'ball'", + "\t\t\tplace: Motion(Place(-10m 10m) Velocity(5m/s 15m/s 10°/s))", + "\t\t\tmatter: Matter(1kg 0.9)", + "\t\t\tscale: Collision('ball' 'ground')•ø ? 1 2)", + "\t\tShape(Rectangle(-10m 0m 10m -2m) name: 'ground')", + "\t]", + ")" + ], + [ + "FunctionDefinition", + "excited", + "It's even possible to know when some @Output bumps into another output with related stream called @Collision.", + "We just need to give names to our two @Output. How about 'ball' and 'ground'?", + "Then, we @Collision will give us a @Rebound when they touch and @None with they don't.", + "Let's make the ball scale up each time it hits the ground for emphasis!" + ], + null, + [ + "fix", + "Stage([Phrase('🏀' 1m place: Motion(Place(0m 10m)) matter: Matter(2kg 0.8)) Shape(Rectangle(-10m 0m 10m -1m))])" + ], + [ + "FunctionDefinition", + "kind", + "There's so much more you can do with @Motion, @Collision, and @Shape!", + "I hope you'll try lots of bouncy things." + ] + ] + }, + { + "title": "Let's talk", + "subtitle": "Chat", + "concept": "Chat", + "performance": ["fit", "Phrase('🗣️')"], + "lines": [ + ["fit", "Phrase('🗣️')"], + [ + "FunctionDefinition", + "kind", + "Sometimes a performance is an interaction. The audience says something and we say something back.", + "That's what @Chat is for. When you use it, a little box will appear on stage for the audience to type in and when they submit their message, @Text will be added to the stream for the program to respond to." + ], + null, + ["edit", "Chat()"], + [ + "FunctionDefinition", + "kind", + "Here's the simplest way to use it. You type something, and then the stage shows it, because the program's value is the @Chat's value." + ], + null, + ["edit", "Chat().has('oo') ? 'choo choo' 'hmm'"], + [ + "FunctionDefinition", + "kind", + "It's more fun to check the value of the chat message to shape the response of the program. This little example responds to any message with consecutive o's with a train sound!" + ] + ] + }, + { + "title": "Say what?", + "subtitle": "Webpage", + "concept": "Webpage", + "performance": [ + "fix", + "Webpage('https://www.nytimes.com')" + ], + "lines": [ + ["edit", "Phrase('🛜')"], + [ + "FunctionDefinition", + "kind", + "So long ago, we heard you had this thing called the internet? I think that's how you're here, right?", + "Well we thought it would be really cool to bring words from the internet /here/, so you can play with them." + ], + null, + ["edit", "Webpage('https://www.nytimes.com')"], + [ + "FunctionDefinition", + "kind", + "Here's how it works: you just give what I think is called a 'URL' to us, and if its an HTML page, we'll pull all the phrases out of it and give it you you in a @List.", + "Like here, these are some news phrases." + ], + null, + ["edit", "Webpage('https://www.nytimes.com' 'h2')"], + [ + "FunctionDefinition", + "kind", + "You can also filter the words with something I think you call a 'CSS' query? Like we heard that 'h3' means 'level 3 header', so here are all the phrases in headers on the page." + ], + null, + [ + "edit", + "words: Webpage('https://www.nytimes.com' 'h2')\n\nwords•[''] ? Group(Stack() words.subsequence(1 5).translate(ƒ(word) Phrase(word resting: Sequence(spin() 1s)))) ø" + ], + [ + "FunctionDefinition", + "kind", + "Once you have a list of words, you can do anything with them! Like grab the first five and turn them into spinning phrases, of course." + ] + ] + }, + { + "title": "On cue", + "subtitle": "Reaction", + "concept": "Reaction", + "performance": ["use", "fit", "Symbol", "…"], + "lines": [ + ["fit", "Phrase('…' resting:Pose(rotation: 120°))"], + [ + "FunctionDefinition", + "neutral", + "All of these streams that I've shown you come from your world. But sometimes, it's helpful to create streams of your own, based on these other streams. That's where my friend @Reaction comes in! @Reaction, are you around?" + ], + [ + "Reaction", + "excited", + "Yeah yeah yeah! It's @FunctionDefinition! How are you doing? Everything has been so… constant, lately. Have you noticed that?" + ], + null, + ["fit", "Phrase('…' resting:Pose(rotation: 240°))"], + [ + "FunctionDefinition", + "curious", + "You mean the silence? Yes, nothing's really changed, has it, since the last person left? What's that been like for you?" + ], + [ + "Reaction", + "sad", + "Super strange, super strange. My whole life has been about change, always listening and watching for new inputs from people, helping transform them into values. But there hasn't been anything. Until just a moment ago… Wait … is that a person?" + ], + null, + ["fit", "Phrase('…' resting:Pose(rotation: 360°))"], + [ + "FunctionDefinition", + "excited", + "Yes! This is our new potential director. I was just showing them @Time, @Key, @Pointer, @Button, @Volume, and @Random, so you probably noticed all the new inputs they were bringing from their world." + ], + [ + "Reaction", + "excited", + "Yesssss, change is coming! Can I show you what I do?" + ], + ["FunctionDefinition", "eager", "Yes, please do!"], + null, + [ + "Reaction", + "serious", + "Okay, so I need three things from you: a condition for change, an initial value, and a next value.", + "The *initial* value is whatever value I should make before any change has happened. It's just a normal expression, of any kind!", + "Then you put \\…\\ after the initial value to tell me that the value can change.", + "After \\…\\, give me *condition* that evaluates to \\⊤\\ or \\⊥\\. It should generally check one or more streams — otherwise, there's nothing changing, since the only source of change in a performance is streams.", + "Then put another \\…\\ after the condition to tell me that the value can change.", + "Finally, the *next* value is whatever value I should make whenever the condition changes." + ], + ["conflict", "_ … _•? … _"], + null, + [ + "Reaction", + "serious", + "Here's an example. See the @Key stream? Putting \\∆\\ before it asks, 'Did this stream change'? Before it changes, I evaluate to the initial value, \\1m\\. But when the space key is pressed, @Program reevaluates, and I evaluate to the *next* expression, which is \\1m\\ plus whatever the previous stream value was, that's represented by \\.\\. This adds 1m to the size of the phrase, making the word get bigger and bigger." + ], + ["fit", "Phrase('hi' size: 1m … ∆ Key(' ') … 1m + .)"], + null, + [ + "FunctionDefinition", + "kind", + "@Reaction, that is so cool. Do you want to introduce @Changed? You seem to work with them closely." + ], + [ + "Reaction", + "kind", + "Yes, @Changed and I are best buddies! They help me know when something has changed. They're like a stream whisperer, listening closely to the director's world…" + ], + null, + [ + "Changed", + "eager", + "Wow, stream whisper, that seems a bit extreme..." + ], + [ + "Reaction", + "serious", + "Oh hi @Changed! Do you want to say more about what you do?" + ], + [ + "Changed", + "bored", + "I mean, I just tell you if a stream changed. Give me a stream, and I'll check. That's it." + ], + [ + "Reaction", + "confused", + "Well, it's more than that right?" + ], + [ + "Changed", + "bored", + "Not really. That's kind of it. I mean, I'm good at it, but that's my only thing." + ], + ["Reaction", "confused", "…"], + null, + [ + "Reaction", + "eager", + "Okay. Well, I think you're more important that than. Because I'm pretty useless without you! For example, if you give me a condition that doesn't check a stream, I'm never going to create a new value. Like here, the condition a @Boolean from @Button, but without you, I only ever change with the button ." + ], + [ + "fit", + "Phrase('hi' size: 1m … Key(' ') = ' ' … 1m + .)" + ], + null, + [ + "FunctionDefinition", + "curious", + "Oh, that makes sense. And @Reaction, you work with any stream?" + ], + [ + "Reaction", + "eager", + "Yes, any stream! And actually, even myself. So if you make a reaction, and want to make a reaction that reacts to it reacting, you can do that too. But we won't worry about that now, since that doesn't usually come up in simple performances." + ], + null, + [ + "FunctionDefinition", + "curious", + "Thank you @Reaction. Will you be around to help as I show our director the rest of our beautiful Verse?" + ], + [ + "Reaction", + "happy", + "Yes, of course, any time. I can't wait to see your inspirations!!" + ] + ] + } + ] + }, + { + "title": "Take the stage", + "performance": ["use", "fix", "RainingEmoji"], + "scenes": [ + { + "title": "Output", + "subtitle": null, + "performance": ["use", "fix", "StaticRainingEmoji"], + "lines": [ + ["use", "fit", "Symbol", "😀"], + [ + "FunctionDefinition", + "happy", + "So what do you think so far? I think the Verse is pretty neat, mostly because the characters in it are so neat. Everyone is just so special!" + ], + null, + ["use", "fit", "Symbol", "🥱"], + [ + "FunctionDefinition", + "curious", + "You're bored? Oh my. I thought all of this would be so interesting! What were you hoping for?" + ], + null, + ["use", "fit", "Symbol", "😴"], + [ + "FunctionDefinition", + "serious", + "I see. Text and numbers and lists and streams are boring. I guess I really haven't shown you all the things we can make with all of this. Maybe it's time we start talking about output." + ], + null, + ["use", "fit", "Symbol", "🤗"], + [ + "FunctionDefinition", + "neutral", + "You've seen a lot of output already. Every time @Program evaluates, it results in a value, and @Program shows that value on stage. But so far you've only seen things like numbers, text, lists. I get it, you just want to see full performances, just like we do!" + ], + null, + ["use", "fit", "Symbol", "💬"], + [ + "FunctionDefinition", + "eager", + "Remember that output I showed you a long time ago, @Phrase? That's where the performances really begin. Let's start there! And then I'll show you ways of building ever more interesting performances from that building block. Let me introduce you!" + ] + ] + }, + { + "title": "Say what?", + "subtitle": "Phrase", + "concept": "Phrase", + "performance": ["use", "fit", "Symbol", "💬"], + "lines": [ + [ + "FunctionDefinition", + "curious", + "@Phrase? Are you out there?" + ], + [ + "Phrase", + "excited", + "Out and proud my darling, how are you? You look so glamorous today! I would love to get you on stage one of these days." + ], + null, + [ + "FunctionDefinition", + "shy", + "Oh, the stage isn't for me, I'm more than happy to be backstage, tinkering with the set." + ], + [ + "Phrase", + "curious", + "Don't be modest, you are every bit as fabulous as me. All you need is a bit of color, a flattering font, and you would be wonderful. You have so much to share! Speaking of, we haven't put on a show in forever, have we? Has it been quiet? You know how much I talk to myself, I can never tell." + ], + null, + [ + "FunctionDefinition", + "kind", + "It has been quiet. Ever since our last director left, it's been a void. But that is changing! We have a new person! We've been meeting the whole family, @Program, @ExpressionPlaceholder, @Evaluate, all the values, all the collections. We just spent time with all of the streams too, and @Reaction and @Conditional. I'm starting to feel things hum. But I haven't introduced our new director here too much about what you do on stage? This is so your world, and not mine, I figured we'd come to you first." + ], + null, + [ + "Phrase", + "happy", + "Well you came to the right place. I love talking about all things stage life. I can't wait to show you all the wonderful little things we do here on stage!" + ], + [ + "FunctionDefinition", + "excited", + "Let the show begin!" + ], + null, + [ + "Phrase", + "excited", + "So I know you've seen me do this." + ], + ["edit", "Phrase('hi')"], + null, + [ + "Phrase", + "kind", + "That, my darling, is the simplest way to get a word on stage. But there's so much more! For example, did you know that you can style the text you give me by working with @FormattedTranslation? You haven't met them yet, but all you have to do is put special symbols around your text? Behold: bold!" + ], + ["edit", "Phrase(`*hi*`)"], + null, + [ + "Phrase", + "kind", + "Not enough sass for you? How about underline, italics, light text, and extra bold text, *all at once*?" + ], + ["edit", "Phrase(`/I/ _am_ ^the^ /fabulous/ 💬!`)"], + null, + [ + "Phrase", + "kind", + "Still not impressed?", + "Mix them all together!" + ], + ["edit", "Phrase(`/_*I am the fabulous*_/ 💬!`)"], + null, + [ + "Phrase", + "kind", + "And if you ever want to use any of these special formatting characters as text instead of formatting, you can just repeat them, kind of like in @Text, and I'll just use the character literally." + ], + [ + "edit", + "Phrase(`Format with /italic/ (//), _underline_ (__), ~light~ (~~), /bold/ (**), ^extra bold^ (^^) `)" + ], + null, + [ + "Phrase", + "excited", + "But I can do more than just style text. For example, I can take a @Phrase/size, measured in meters \\m\\. Try changing the size to any size you like!" + ], + ["edit", "Phrase('hi' 2m)"], + null, + [ + "Phrase", + "kind", + "That size can be any expression. For example, say we wanted it to grow as @Time ticks. We can take time, multiply it by a fraction of a meter, and glorious, tick tick tick, hi hi hi. Try changing the frequency or the multiplier. See what beautiful growth you can create!" + ], + ["fit", "Phrase('hi' Time(100ms) · 0.001m/ms)"], + null, + [ + "Phrase", + "excited", + "Do you like costumes? I loooooove costumes. My @Phrase/face is a costume. Pick any of the supported faces to spice up the word you've chosen." + ], + [ + "use", + "fix", + "Symbol", + "hi' Time(100ms) · 0.001m/ms 'Poor Story" + ], + null, + [ + "Phrase", + "neutral", + "Need me to be somewhere else on stage? Places please! A @Place is just an \\x\\, \\y\\, and optional \\z\\ position, in meters \\m\\. Try changing the place to a different location, by editing the numbers, or dragging the @Phrase on stage." + ], + [ + "fit", + "Phrase('hi' Time(100ms) · 0.001m/ms 'Poor Story' Place(2m 2m))" + ], + null, + [ + "Phrase", + "curious", + "Do you ever feel a little off axis? Maybe you give the world a little @Pose/rotation with rotation. Try changing the rotation value to twist me around!" + ], + [ + "fit", + "Phrase('hi' Time(100ms) · 0.001m/ms 'Poor Story' Place(2m 2m) rotation: 20°)" + ], + null, + [ + "Phrase", + "happy", + "Or maybe we have a little fun, and link rotation to @Time! Wheeeee. Any guesses on how to make me spin faster? See if you can figure it out…" + ], + [ + "fit", + "Phrase('hi' 3m 'Poor Story' rotation: Time(10ms) · 1°/ms)" + ], + null, + [ + "Phrase", + "serious", + "Now's an outstanding time to remind you that @FunctionDefinition here requires inputs to be in a particular order, so if you put them out of order, they. Are. Going. To. Complain." + ], + [ + "FunctionDefinition", + "shy", + "I will… I like things… tidy… Can you put them in the right order? You can cut and paste with the keyboard or click and drag expressions to rearrange them." + ], + [ + "conflict", + "Phrase('hi' 'Poor Story' 3m Time(10ms) · 1°/ms Place(2m 2m))" + ], + null, + [ + "Phrase", + "kind", + "Only want to give a particular property? Just name the one you want. Here we name @Phrase/size and @Phrase/rotation." + ], + [ + "edit", + "Phrase('hi' size: 3m rotation: Time(10ms) · 0.1°/ms)" + ], + null, + [ + "Phrase", + "neutral", + "Now that we have all those out of the way, we can talk about dancing, darling! Dancing is one of my favorite things to do. There are *four* ways I move. First, I can @Phrase/entering. Enter is my way of entering the stage. If you don't tell me how to enter, I'll just BLIP appear on stage like I teleported there. But if you give me @Pose. I'll start with the pose you give me, then move to my resting pose. For example, let's make me fade in from invisible to oh-so-in-your face visible." + ], + ["edit", "Phrase('hi' entering: Pose(opacity: 0))"], + null, + [ + "Phrase", + "curious", + "Didn't see it? Did I move too fast for you? That's because my duration is \\0s\\ by default. Slow me down with a duration, which tells me how long I should take to move between poses. I made this one nice and slow for you, but try changing duration to higher and lower numbers." + ], + [ + "edit", + "Phrase('hi' entering: Pose(opacity: 0) duration: 5s)" + ], + null, + [ + "Phrase", + "neutral", + "Now, say I was moving. We'll set my place to time, so I move to the right a bit every second. But if we set a @Phrase/moving @Pose, and have the @Pose/rotation \\5°\\ and maybe a little color, every time my place changes, I'll glide across the stage with the cutest little tilt." + ], + [ + "fit", + "Phrase('hi' size: 5m place: Place(Time(1000ms) · 0.001m/ms 0m) moving:Pose(rotation: 5°) duration: 0.5s)" + ], + null, + [ + "Phrase", + "curious", + "Not in the mood for cute? How about you make me a little serious by having me slide across straight by changing my @Phrase/style. It's really subtle, but styles can really change the /emotion/ of a movement." + ], + [ + "fit", + "Phrase('hi' size: 5m place: Place(Time(1000ms) · 0.001m/ms 0m) moving:Pose(rotation: 5°) duration: 0.5s style: “straight”)" + ], + null, + [ + "Phrase", + "excited", + "And for the coup de grâce, let's have me @Phrase/exiting in style. We can play with @Conditional and have me exit stage after 3 seconds." + ], + [ + "fit", + "Time(1000ms) < 3000ms ? ", + "Phrase('hi' size: 5m place: Place(Time(1000ms) · 0.001m/ms 0m) moving:Pose(rotation: 5°) duration: 0.5s) ", + "Phrase('')" + ], + null, + [ + "Phrase", + "surprised", + "Not the exit you were hoping for? The disappearing act is a bit harsh, ain't it? Give me an @Phrase/exiting @Pose, and I'll glide off on stage toward whatever pose you want. Here we'll have me get large than life, fall upside down, and fade out to @Pose/opacity \\0\\." + ], + [ + "fit", + "Time(1000ms) < 3000ms ? Phrase('hi' size: 5m place: Place(Time(1000ms) · 0.001m/ms 0m) moving:Pose(rotation: 5°) exiting:Pose(scale: 10 rotation: 180° opacity: 0) duration: 0.5s) Phrase('')" + ], + null, + [ + "Phrase", + "serious", + "You probably noticed that I can take up a little space in @Program. If you ever want to make me easier to read, just add some lines between my properties. See how that's so much easier to see?" + ], + [ + "edit", + "Time(1000ms) < 3000ms ?", + " Phrase(", + " 'hi'", + " size: 5m", + " place: Place(Time(1000ms) · 0.001m/ms 0m)", + " moving:Pose(rotation: 5°)", + " exiting:Pose(scale: 10 rotation: 180° opacity: 0)", + " duration: 0.5s", + " )", + " Phrase(“”)" + ], + null, + [ + "FunctionDefinition", + "excited", + "Bravo, bravo, that was just stunning, @Phrase! I'm always blown away by how much you can do with just a few simple ideas. A while ago, I showed our new inspirational friend here about the palette. Do you want to say more about that?" + ], + [ + "Phrase", + "happy", + "Of course! Any time you get tired of fiddling with @Evaluate's inputs, you can always select a phrase on stage, and a palette will appear, allowing you to change any little thing you might want, my size, font, place, poses. There's just one rule: if you set any of those to an expression, instead of just a value, you'll have to change them down in @Program, not in the palette. Dress me up all you like!" + ], + ["edit", "Phrase('dress me up!')"], + null, + [ + "FunctionDefinition", + "curious", + "Wait, Phrase, what about @Color?" + ], + [ + "Phrase", + "sad", + "Omigod omigod omigod, I CANNOT believe I forgot about color. Okay, so any @Pose can have a color, right? But @Color comes in three parts. First, a @Color/lightness between 0 and 100%, which you can think of as how bright a room is, from black to white, with color in the middle at 50%.", + "Then, a @Color/chroma between 0 and 100, which you can think of has how much color there is, from no color gray to full color.", + "And finally, a @Color/chroma, which you can think of like a color wheel, from red to green to blue, in degrees. So you want me to be bright red? Set my rest pose color to \\Color(50% 300 30°)\\." + ], + ["edit", "Phrase('red' color: 🌈(50% 300 30°))"], + null, + [ + "FunctionDefinition", + "excited", + "And want me to shimmer with the rainbow? Take time, get the remainder of dividing by 360, then multiply by degrees and I'll spin around that color wheel all day long!" + ], + [ + "edit", + "Phrase('red' size: 5m color: 🌈(50% 300 (Time() % 360) · 1°/ms))" + ], + [ + "FunctionDefinition", + "happy", + "@Phrase, that is something to be proud of :P I think we're going to go visit @Sequence next, and then maybe @Group and @Stage. You'll be around to help?" + ], + [ + "Phrase", + "kind", + "I wouldn't miss it. Sparkle and shine!" + ] + ] + }, + { + "title": "1, 2, 3, 4, 1, 2, 3, 4", + "subtitle": "Sequence", + "concept": "Sequence", + "performance": ["use", "fix", "DancingEmoji", "💃"], + "lines": [ + ["use", "fit", "DarkVoid"], + [ + "FunctionDefinition", + "kind", + "@Phrase is just wonderful, aren't they? They have so much energy, so many amazing flourishes. Did you know they work closely with our choreographer, @Sequence? @Sequence and @Phrase together can do some incredible things that @Phrase can't do alone. Do you want to meet them?" + ], + null, + [ + "FunctionDefinition", + "excited", + "Yay! @Sequence, we have a guest. Are you back there?" + ], + [ + "Sequence", + "curious", + "@FunctionDefinition! You look beautiful. How long has it been? A week? A month? A century? It was like 1, 2, 3 and then everything was quiet. I feel like I've been dancing alone forever…" + ], + null, + [ + "FunctionDefinition", + "sad", + "It was silent, wasn't it? But I can totally see you dancing alone. I was doing my own choreography all alone too, just having to imagine all of you working together. But it wasn't the same." + ], + [ + "Sequence", + "kind", + "And you an @Evaluate? Are you still…" + ], + null, + [ + "FunctionDefinition", + "shy", + "I just saw them earlier. They… Oh, we have a guest! @Sequence, this is our new director pal. They've come to bring us inspiration!" + ], + [ + "Sequence", + "excited", + "(We're going to come back to that tea, @FunctionDefinition). Director pal, it's so exciting to meet you! Have you come here to learn to dance?" + ], + [ + "FunctionDefinition", + "kind", + "Of course they did! Do you want to show them the steps?" + ], + null, + [ + "Sequence", + "serious", + "Absolutely. You know time? 1, 2, 3, 4, 1, 2, 3, 4? Well I make time beautiful, arranging a sequence of poses over time for @Phrase to follow. You tell me what the poses are and I'll help @Phrase follow the steps. Like this example: our smiley friend here has four poses, and smoothly moves between them." + ], + [ + "fit", + "Phrase('😀' resting:Sequence({0%: Pose() 25%: Pose(offset: Place(0m 1m) scale: 2) 50%: Pose(offset: Place(0m 0m) flipy: ⊤) 75%: Pose(rotation: 45°) 100%: Pose()} 2s))" + ], + null, + [ + "Sequence", + "neutral", + "Here's a simple example of how I work. Here's @Phrase (hi @Phrase!) with the word “dance”, and they have an enter pose that's a @Sequence rather than a single @Pose. Follow me? The sequence has four steps. Straight, tilt left, tilt right, straight. When @Phrase enters, they do this cute little wobble, and then stop. I work with @MapLiteral to map percentages to a @Pose. Each of those percentages are how far through the sequence each @Pose should happen. Try changing the percentages, especially those two middle ones. It changes the flow and style of the wobble." + ], + [ + "edit", + "Phrase(", + " 'dance'", + " entering: Sequence(", + " {", + " 0%: Pose(rotation: 0°)", + " 33%: Pose(rotation: -5°)", + " 66%: Pose(rotation: 5°)", + " 100%: Pose(rotation: 0°)", + " }", + " )", + ")" + ], + null, + [ + "Sequence", + "serious", + "Okay, so now imagine you wanted this to be really fast. By default, I'm pretty quick, so any sequence will be a quarter second and it's done. But what if you wanted it to be even faster? Give me a shorter duration and I'll speed every @Pose up to get it done faster. 1, 2, 3, 4! It doesn't look like a wobble anymore, does it? More like a frantic little shake! See what it looks like if you slow me down to 2 or 3 seconds…" + ], + [ + "edit", + "Phrase(", + " 'dance'", + " entering: Sequence(", + " {", + " 0%: Pose(rotation: 0°)", + " 33%:Pose(rotation: -5°)", + " 66%: Pose(rotation: 5°)", + " 100%: Pose(rotation: 0°)", + " } ", + " duration: 0.05s", + " )", + ")" + ], + null, + [ + "Sequence", + "excited", + "But sometimes, we come up with a lovely move and we just can't help but want to do it over and over, for emphasis! That looks a little violent… try changing my duration and count until we get it just right…" + ], + [ + "edit", + "Phrase(", + " 'dance'", + " entering: Sequence(", + " {", + " 0%: Pose(rotation: 0°)", + " 33%: Pose(rotation: -5°)", + " 66%: Pose(rotation: 5°)", + " 100%: Pose(rotation: 0°)", + " } ", + " duration: 0.1s ", + " count: 4x)", + " )" + ], + null, + [ + "Sequence", + "curious", + "But, you say, what if we wanted to do it forever? You can set a @Phrase/resting to me. For as long as @Phrase is on stage and resting, they'll repeat a sequence. Infinite wobbles!" + ], + [ + "edit", + "Phrase(", + " 'dance'", + " resting:Sequence(", + " {", + " 0%: Pose(rotation: 0°)", + " 33%:Pose(rotation: -5°)", + " 66%: Pose(rotation: 5°)", + " 100%: Pose(rotation: 0°)", + " } ", + " duration: 0.05s", + " )", + ")" + ], + null, + ["use", "fit", "DarkVoid"], + [ + "FunctionDefinition", + "kind", + "@Sequence, this is so great! This is exactly what I was hoping you could show us. But I'm curious, what have you been working on lately, dances of your own? Maybe something that shows everything you're capable of?" + ], + [ + "Sequence", + "excited", + "Oh my yes! @Phrase and I have been working on this new donut dance. It comes my favorite treat with nearly everything I've learned in dance. Do you want to see it?" + ], + ["FunctionDefinition", "excited", "Yes!!!"], + null, + [ + "Sequence", + "serious", + "Yeah, hmm, oooh, up, eee, eee, eee, eee, bam, boo, yeah, hmm, oooh, up, eee, eee, eee, eee, bam, boo, yeah, hmm, oooh, up, eee, eee, eee, eee, bam, boo, …" + ], + ["use", "fit", "DonutDance"], + null, + ["use", "fit", "DonutDance"], + [ + "FunctionDefinition", + "happy", + "@Sequence, that's amazing! How could that not be the next viral dance?" + ], + [ + "Sequence", + "excited", + "You mean next spiral dance. Cheers!" + ] + ] + }, + { + "title": "Places please", + "subtitle": "Group", + "concept": "Group", + "performance": [ + "fit", + "Group(Grid(2 2) [Phrase('1' resting:Sequence(spin() 1s)) Phrase('2' resting:Sequence(spin() 2s)) Phrase('3' resting:Sequence(spin() 3s)) Phrase('4' resting:Sequence(spin() 4s))])" + ], + "lines": [ + ["use", "fit", "Symbol", "☹️"], + [ + "FunctionDefinition", + "neutral", + "Sigh… everyone keeps bringing up @Evaluate, but I don't know what to say. Are you ever so close to someone, and yet so far away?", + "…" + ], + null, + ["use", "fit", "Symbol", "😕"], + [ + "FunctionDefinition", + "serious", + "Sorry. I'm excited to be here with you.", + "I think…", + "I think what will help is introducing you to the rest of us, and then putting on a show, and then I think @Evaluate and I can sort things out." + ], + null, + ["use", "fit", "Symbol", "🙂"], + [ + "FunctionDefinition", + "eager", + "So who's next?", + "Oh, @Group! I can't believe I forgot @Group.", + "This is perfect timing; you know @Phrase and @Sequence now, and @Group is such an integral part of bringing us all together. @Group cares for us all so deeply.", + "@Group? Are you there?" + ], + null, + ["fit", "Group(Grid(2 2) [Phrase('🔳')])"], + [ + "Group", + "neutral", + "@FunctionDefinition, hello, how are you? Where has everyone been? I've been so worried! Are you okay?" + ], + [ + "FunctionDefinition", + "kind", + "I'm okay. We're all okay! The silence is breaking, because we found a person! They're going to be our inspiration." + ], + null, + ["fit", "Group(Grid(2 2) [Phrase('🔳') Phrase('🔳')])"], + [ + "Group", + "happy", + "That's lovely! You're not hurt? Everyone else is here? I felt like I was wandering in the dark, and couldn't see anyone." + ], + [ + "FunctionDefinition", + "kind", + "I'm not hurt. Just a bit rusty. And I haven't seen everyone yet, but almost everyone, and I think everyone is waking up okay. (Though apparently some have been at the beach). We've met nearly everyone. We're getting ready to put on a show! And the best shows always involve you…" + ], + null, + [ + "fit", + "Group(Grid(2 2) [Phrase('🔳') Phrase('🔳') Phrase('🔳')])" + ], + [ + "Group", + "kind", + "A show! I can't wait to help. You kids are always so inspiring, I'm always happy to do my part. What shall I do, where do I start?" + ], + [ + "FunctionDefinition", + "happy", + "Well, we've talked about @Phrase, so maybe start with a bit about your purpose?" + ], + null, + [ + "fit", + "Group(Grid(2 2) [Phrase('🔳') Phrase('🔳') Phrase('🔳') Phrase('🔳')])" + ], + [ + "Group", + "neutral", + "My purpose, yes. Let's see — I think my purpose is to bring everyone together. But I particularly bring @Phrase together, in beautiful shapes and arrangements on stage. Did you know that @Phrase can be in more than one place at once? That's because they aren't so much one text phrase on stage, but a phrase maker, just like I'm a @Group maker. They'll make as many as you need, and then I lay them out on stage, as you direct me. All I need is an @Arrangement, and a list of @Phrase, and I'll do the rest." + ], + null, + [ + "Group", + "excited", + "Here's a simple example. Here I'm using a @Stack arrangement, which creates a vertical arrangement of @Phrase, or other @Group. See how I make a tidy little stack of words? They're arranged just so, with a little breathing room for everyone and everyone centered. Everyone is so cute!" + ], + [ + "edit", + "Group(", + " Stack() ", + " [", + " Phrase('one')", + " Phrase('two')", + " Phrase('three')", + " ]", + ")" + ], + null, + [ + "Group", + "serious", + "But sometimes we all need a little space. So you can give @Stack some padding. Try changing the padding to a different @NumberLiteral!" + ], + [ + "edit", + "Group(", + " Stack(0 2m) ", + " [", + " Phrase('one')", + " Phrase('two')", + " Phrase('three')", + " ]", + ")" + ], + null, + [ + "Group", + "happy", + "Just as with anything in the Verse, that padding value can come from anything, like input. Sometimes we grow apart don't we? Let's dance that idea by making the padding grow over time…" + ], + [ + "edit", + "Group(", + " Stack(0 Time(100ms) · 0.001m/ms) ", + " [", + " Phrase('one')", + " Phrase('two')", + " Phrase('three')", + " ]", + ")" + ], + null, + [ + "Group", + "surprised", + "We also have a @Row, which is a horizontal arrangement." + ], + [ + "edit", + "Group(", + " Row(0 Time(100ms) · 0.001m/ms) [", + " Phrase('one')", + " Phrase('two')", + " Phrase('three')", + " ]", + ")" + ], + null, + [ + "Group", + "curious", + "Sometimes it's nice to use two dimensions instead of one. If you tell me how many rows and columns you want, I'll make a @Grid of phrases. Just make sure to give me enough phrases to fill the grid! You can also give @Grid padding and a cell size if you want to be extra precise. Grids are layed out a row at a time, so put your @Phrase list in order of rows." + ], + [ + "edit", + "Group(", + " Grid(2 2) [", + " Phrase('one')", + " Phrase('two')", + " Phrase('three')", + " Phrase('four')", + " ]", + ")" + ], + null, + [ + "Group", + "excited", + "And if you wanted a very specific arrangement? You could use @Free, and tell me exactly where you want all the phrases. Just be sure to give a place to each @Phrase, otherwise I'll just place it at \\Place(0m 0m\\)." + ], + [ + "edit", + "Group(", + " Free() [", + " Phrase('one' place: Place(-2m 2m))", + " Phrase('two' place: Place(-1m 1m))", + " Phrase('three' place: Place(0m 0m))", + " Phrase('four' place: Place(1m -1m))", + " Phrase('five' place: Place(2m -2m))", + " ]", + ")" + ], + null, + [ + "Group", + "curious", + "And did you know you can also place me inside myself? A @Group in a @Group in a @Group, it's very silly. This can make it possible to make a @Grid of @Stack for example." + ], + [ + "edit", + "Group(", + " Grid(2 2) [", + " Group(Stack() [Phrase('one') Phrase(“two”)])", + " Group(Stack() [Phrase('three') Phrase(“four”)])", + " Group(Stack() [Phrase('five') Phrase(“six”)])", + " Group(Stack() [Phrase('seven') Phrase(“eight”)])", + " ]", + ")" + ], + null, + [ + "Group", + "surprised", + "Hm, that kind of looks like a 4 by 2 grid, doesn't it? Let's make it a little clearer by tilting two of the stacks. Oh, yes, you can give me all the same properties that @Phrase takes!" + ], + [ + "edit", + "Group(", + " Grid(2 2) [", + " Group(Stack() [Phrase('one') Phrase(“two”)])", + " Group(Stack() [Phrase('three') Phrase(“four”)] resting:Pose(rotation: 45°))", + " Group(Stack() [Phrase('five') Phrase(“six”)])", + " Group(Stack() [Phrase('seven') Phrase(“eight”)] resting:Pose(rotation: 45°))", + " ]", + ")" + ], + null, + ["use", "fit", "DarkVoid"], + [ + "Group", + "curious", + "Was that good, @FunctionDefinition? Did I cover everything?" + ], + [ + "FunctionDefinition", + "happy", + "That was better than good! I think you showed our new director here just how much is possible. Is there anything else you want to share?" + ], + null, + [ + "Group", + "serious", + "I don't think so… I'm always learning new arrangements, so always check back for new designs I've come up with! And @FunctionDefinition, how are you and @Evaluate doing? I know the last time I saw you talking, things were bumpy…" + ], + [ + "FunctionDefinition", + "shy", + "I… I'd rather not talk about it right now." + ], + [ + "Group", + "kind", + "Okay. I'm always here if you want to chat." + ] + ] + }, + { + "title": "Stage… right?", + "subtitle": "Stage", + "concept": "Stage", + "performance": [ + "fix", + "Stage([Phrase('🎭' 5m)] background: Color(0% 0 0°))" + ], + "lines": [ + [ + "fix", + "Stage([Phrase('🎭' 5m resting:Sequence(bounce(5m) 2s))] background: Color(0% 0 0°))" + ], + [ + "FunctionDefinition", + "excited", + "Okay, there's someone who's been here all along, but we haven't really done a proper introduction. May I introduce @Stage!" + ], + [ + "Stage", + "neutral", + "HELLO, @FunctionDefinition HELLO PERSON." + ], + null, + [ + "fix", + "Stage([Phrase('🎭' 5m resting:Pose(rotation: 25° scale: 5))] background: Color(0% 0 0°))" + ], + [ + "FunctionDefinition", + "happy", + "@Stage, this person is our new director. They're so excited to finally meet you!" + ], + [ + "Stage", + "neutral", + "HELLO DIRECTOR. ARE YOU HERE TO INSPIRE?" + ], + null, + [ + "fix", + "Stage([Phrase('🎭' 5m resting:Pose(rotation: -150° scale: 10))] background: Color(0% 0 0°))" + ], + [ + "FunctionDefinition", + "kind", + "Indeed they are, with all kinds of expressions from their world." + ], + [ + "Stage", + "neutral", + "I AM HERE TO SERVE. TELL ME WHAT TO PUT ON STAGE, AND I WILL." + ], + null, + [ + "fix", + "Stage([Phrase('🎭' 5m)] background: Color(0% 0 0°))" + ], + [ + "FunctionDefinition", + "neutral", + "@Stage is one of a kind, and always there. In fact, if you give @Program a @Phrase or @Group, @Program will show a @Stage, even if you don't mention them. But if you do mention them, you can be more specific about how you want the stage to appear." + ], + null, + [ + "FunctionDefinition", + "neutral", + "Maybe let's start with a simple example. This just gives @Stage a list of one @Phrase. You don't have to mention @Stage here; this just shows what's happening behind the scenes when you give @Phrase to @Program." + ], + ["edit", "Stage([Phrase(“🐈”)])"], + null, + [ + "FunctionDefinition", + "neutral", + "But say you want the stage to have a different background color, such as black." + ], + ["Stage", "surprised", "BRRRRR…"], + [ + "edit", + "Stage([Phrase(“🐈”)] background: Color(0 0 0°))" + ], + null, + [ + "FunctionDefinition", + "neutral", + "You can also frame the stage, for example, with a @Rectangle, which takes a top left place and bottom right place. See how the kitty is a little bit out of frame?" + ], + ["Stage", "surprised", "THE WORLD IS CLOSING IN…"], + [ + "edit", + "Stage([Phrase(“🐈” place: Place(-2.5m))] background: Color(0 0 0°) frame: Rectangle(-2m -2m 2m 2m))" + ], + null, + [ + "FunctionDefinition", + "neutral", + "You can also apply all of the same properties to @Stage as you can a @Group or @Phrase. Let's tilt the whole stage!" + ], + ["Stage", "surprised", "WHOA, CAREFUL NOW…"], + [ + "edit", + "Stage(", + " [Phrase(“🐈” place:Place(-2.5m))]", + " background: Color(0 0 0°)", + " resting: Pose(rotation: 30°)", + " frame: Rectangle(-2m -2m 2m 2m)", + ")" + ], + null, + [ + "FunctionDefinition", + "kind", + "There's much more you can do with @Stage, but you can explore with them anytime. Right @Stage?" + ], + ["Stage", "excited", "ALWAYS!"] + ] + }, + { + "title": "Is there someone named...", + "subtitle": "Choice", + "concept": "Choice", + "performance": ["fix", "Phrase('🔘' 10m)"], + "lines": [ + [ + "fix", + "Phrase('🔘' 10m entering: Sequence({0%: Pose(offset: Place(0m 0m)) 50%: Pose(offset: Place(0m -0.2m)) 100%: Pose(offset: Place(0m 0m))} 1s count: 3x))" + ], + [ + "FunctionDefinition", + "serious", + "So you know @Key, @Pointer, and @Button, the streams we just talked about? They can be very fun, but they have one problem: not everyone in the audience can use them. Some people do not have hands, or cannot use their hands, or cannot use them precisely to click keys or use a mouse. We know that many some people use their voices to communicate with our world, or even their eyes. So using @Key, @Pointer, or @Button means some people in your audience won't be able to participate." + ], + null, + [ + "FunctionDefinition", + "kind", + "Everyone should be able to participate! So now that we've talked about @Phrase in more detail, I wanted to show y ou one final stream, @Choice, which is a stream of @Phrase names that have been selected, independent of how it was selected. For example, an audience might use a mouse to click on a @Phrase, or they might use a keyboard to select it, or there might be other devices they use. Whatever they use, @Choice will contain their latest selection." + ], + null, + [ + "FunctionDefinition", + "excited", + "Here's a simple example. See how it has three phrases? The first two have two important details. First, they're set to be selectable. This tells @Stage that if they are clicked, or if the keyboard is used to select them, that they are chosen. The second detail is that they have a @Phrase/name. That gives @Stage a unique name for the phrase that was chosen. It's important that it's unique so that @Stage knows what was chosen. The third phrase is set to a @Choice stream, which is a series of @Phrase or @Group names are selected. Here, we're just giving the name to another phrase, so that it shows what name is selected. Try clicking the cat or dog, or using the keyboard to select one. See how the third @Phrase shows the name selected?" + ], + [ + "Choice", + "neutral", + "cat... 'dog'... 'cat'... 'dog'..." + ], + [ + "edit", + "Stage(", + " [Group(Stack() [", + " Phrase('🐱' name:'cat' selectable:⊤)", + " Phrase('🐶' name: 'dog' selectable:⊤)", + " Phrase(Choice())", + " ])", + "])" + ], + null, + [ + "FunctionDefinition", + "serious", + "@Choice really is the best way to listen to the audience. Only use @Key, @Pointer, or @Button if you have no other option, and use it knowing that some in your audience won't be able to enjoy your performance." + ] + ] + } + ] + }, + { + "title": "Callbacks", + "performance": ["use", "fit", "DarkVoid"], + "scenes": [ + { + "title": "Memories", + "subtitle": null, + "performance": ["use", "fit", "Symbol", "💭"], + "lines": [ + ["FunctionDefinition", "curious", "…"], + null, + ["use", "fit", "Symbol", "🤯"], + [ + "FunctionDefinition", + "neutral", + "Sometimes I just need to pause and reflect on how incredible my little community is. We are all so different, and none of us could perform alone. But together, we can do such amazing things!" + ], + null, + ["use", "fit", "Symbol", "🧠"], + [ + "FunctionDefinition", + "kind", + "But it seems no matter how amazing we are, we always forget, and end up repeating ourselves. And so there's one more there's one more group I want to introduce you to. They are how we *remember*, and how we organize our memories. Without them, everything so much of our work would have to be done over, and over, and over, and we'd never be able to put on the most exciting shows." + ] + ] + }, + { + "title": "Naming", + "subtitle": "Bind", + "concept": "Bind", + "performance": ["use", "fit", "Symbol", ":"], + "lines": [ + ["fit", "Phrase(':' rotation: 90°)"], + [ + "FunctionDefinition", + "curious", + "@Bind? There's someone I want to introduce you to." + ], + [ + "Bind", + "curious", + "@FunctionDefinition? Oh wow, it is you. It has been absolutely silent for far too long. Who's your friend here?" + ], + null, + [ + "fit", + "Phrase(':' resting:Pose(scale: 10ms ÷ Time()))" + ], + [ + "FunctionDefinition", + "kind", + "They're our new director! They've come here to inspire us with new ideas, new expressions." + ], + [ + "Bind", + "excited", + "Seriously? That would be amazing. I haven't felt inspired in a long time. I feel like all I've been doing is just waiting…" + ], + null, + [ + "fix", + "Phrase(':' 10m resting:Sequence(bounce(3m) 1s))" + ], + [ + "FunctionDefinition", + "curious", + "Well now that you know, what do you want to do most right now?" + ], + [ + "Bind", + "serious", + "Name things. Name everything! Name everyone. I haven't named anything in forever." + ], + [ + "FunctionDefinition", + "curious", + "I haven't told our inspiration here about names at all, aside from the names of all of the characters we've met. Do you want to explain how names work here?" + ], + null, + ["use", "fit", "Symbol", ":"], + [ + "Bind", + "excited", + "Absolutely! So names… you know how every expression makes a value?" + ], + [ + "FunctionDefinition", + "kind", + "We talked about values! Like @Number, @Text, @None, @List, @Set, @Map..." + ], + [ + "Bind", + "excited", + "Right! So like, values, when we make them, they just kind of get passed around by us, like a ball, from expression to expression, until @Program makes the final value it gives to @Stage to show. But sometimes, rather than passing a value around, it's helpful to set it aside, and save it for later, for some other expression. That's what a @Phrase/name is for. I name things so we can use them later." + ], + null, + [ + "Bind", + "serious", + "So like here's a really simple example. Let's say we want to name a number. We just say the name, then :, then the number we want. Simple, right? Now any time we use the name number in an expression, it will evaluate to \\1\\. Like here, where we name it, then use its name to give @Program whatever value it has." + ], + ["edit", "number: 1", "number"], + null, + [ + "Bind", + "serious", + "And like, you can tell me what kind of value the name should be by giving me a type with the \\•\\ symbol. So like, if you wanted to make sure that number was a number, you'd say this. That says to name the value \\number\\ and that the value must be a @Number." + ], + ["edit", "number•#: 1", "number"], + null, + [ + "Bind", + "eager", + "But like, what if you gave me something that was /not/ a number? Then I'd complain, because you said it was supposed to be a number, but you gave me some text. So I don't know what to do. See?" + ], + ["conflict", "number•#: 'oh hi'", "number"], + null, + [ + "Bind", + "serious", + "But okay, by now you must be thinking, *Why would anyone name a number or text like this???*. Well, imagine, like, you were listening to @Key, and you want know if it's one of a set of secret letters, and show a @Phrase with a big \\⊤\\ if it's a magic letter, and small \\⊥\\ if it's not. We might start with something like this. That gets us the \\⊤\\ or \\⊥\\.", + "This is great, when you press one of those letters, \\⊤\\ and when you press something else, you get \\⊥\\. Good." + ], + ["edit", "[ 'a' 'e' 'i' 'o' 'u'].has(Key())"], + null, + [ + "Bind", + "serious", + "Now, let's make the phrase. We put that @List/has expression in for the text and convert it to text. Now we get @Phrase on stage as \\⊤\\ or \\⊥\\. Good!" + ], + [ + "edit", + "Phrase([ 'a' 'e' 'i' 'o' 'u'].has(Key())→'')" + ], + null, + [ + "Bind", + "curious", + "Now comes the problem part. How do we change the size of the @Phrase? Well we already figured out how to check if it's a magic letter, so we could just copy it, and if it's \\⊤\\, then make it size \\2m\\ and otherwise if it's \\⊥\\, make it \\1m\\. That works, but you see how we have to evaluate the same expression twice?" + ], + [ + "edit", + "Phrase(", + " [ 'a' 'e' 'i' 'o' 'u' ].has(Key())→''", + " [ 'a' 'e' 'i' 'o' 'u' ].has(Key()) ? 2m 1m", + ")" + ], + null, + [ + "Bind", + "excited", + "That's where I come in! See, what you can do is just evaluate the expression and name the resulting value. Magic, right? All you have to do is put a name and \\:\\ in front of an expression and the value of that expression gets a name. Then you can use that name anywhere after that expression to refer to its value. Weird, huh? You want to see how it works? Try pressing the ← in the timeline and go backwards a few steps to where magic is first named. See how \\magic\\ gets the value of the \\has\\? And then how each place \\magic\\ is referred to by name, the same value gets placed?" + ], + [ + "edit", + "magic: [ 'a' 'e' 'i' 'o' 'u'].has(Key())", + "Phrase(", + " magic→''", + " magic ? 2m 1m", + ")" + ], + null, + [ + "Bind", + "serious", + "You know, you could always just duplicate the expressions you write. It would be the same show. It's just kind of wasteful. I mean, we have to create the exact same values over and over, and then if you change your mind about an expression, you have to change it everywhere. That, and what if you change it in one place, but forget to change it in other places? Like, imagine if you also made the color change, so you had the same expression three times. And then imagine you wanted to add a letter to our magic letter list with this. You have to do it three times! You might forget one, or make a typo. How are you supposed to express your artistic vision if some of us aren't doing what you intended?" + ], + [ + "edit", + "Phrase(", + " [ 'a' 'e' 'i' 'o' 'u' 'z'].has(Key())→''", + " [ 'a' 'e' 'i' 'o' 'u' 'z'].has(Key()) ? 2m 1m", + " color: Color(50% 100 [ 'a' 'e' 'i' 'o' 'u' 'z'].has(Key()) ? 180° 0°)", + ")" + ], + null, + [ + "Bind", + "kind", + "But like, if you name the expression, you just have to do it once. And look how much easier that is to read, too." + ], + [ + "edit", + "magic: [ 'a' 'e' 'i' 'o' 'u' 'z'].has(Key())", + "Phrase(", + " magic→''", + " magic ? 2m 1m", + " color: Color(50% 100 magic ? 180° 0°)", + ")" + ], + null, + [ + "FunctionDefinition", + "excited", + "@Bind, that was such a good example! You know I love names. I was curious, are there also some things that can go wrong with names?" + ], + [ + "Bind", + "sad", + "Yeah, hm. There are. Like, suppose we did this. See the problem? I highlighted it. This program defines \\veggies\\ after it's used, which really confuses me. Because things are evaluated in reading order, so like, we're reading this program and we get to the word \\veggies\\, and we're like, who's \\veggies\\? And only after the \\total\\ is \\veggies\\ like, “here I am!” and then the whole production falls apart." + ], + [ + "conflict", + "fruits: 5", + "total: fruits + veggies", + "veggies: 3", + "total" + ], + null, + [ + "Bind", + "serious", + "Or, like here's an example where we give two different values the same name. And so we evaluate \\5\\, and name it \\fruits\\, and then we evaluate \\10\\… and then we name it \\fruits\\?? Like, there's already a \\fruits\\, so which \\fruits\\ are you talking about? Because see, once you name a value, you can't give it a new value. That name and value are bound together, until @Program is done evaluating. We don't want anyone getting confused about who is who." + ], + [ + "conflict", + "fruits: 5", + "fruits: 10", + "total: fruits + fruits", + "total" + ], + null, + [ + "Bind", + "kind", + "I guess there's one last one. Say you have this. See what happened here? We named \\veggies\\, but then we never used it. That's usually a bad sign that you're leaving someone out, or didn't use the right name. Like, maybe you're just not using it, but then why is it there?" + ], + ["conflict", "fruits: 5", "veggies: 10", "fruits + 3"], + null, + [ + "FunctionDefinition", + "neutral", + "This is so helpful @Bind, this is so great. Are you sure there's nothing else?" + ], + [ + "Bind", + "eager", + "Oh! Yes, something really important. So like, one name is good, right? But sometimes, multiple names is better? Like if you wanted to name something in multiple person languages, so everyone can read it? So like, say you wanted to say fruit in multiple languages.", + "Put the text cursor on the name \\fruit\\. See how there are actually three names in there, and they each have a two letter tag like \\/en\\? Names hide if they're in a language that you haven't chosen.", + "Go down to the ⚙ and choose Spanish, for example, and you'll see the English and Spanish names. So like, one value, but three names, and you can use any of them to get that value. If you tell us what languages you want, we'll show whichever ones are available. The more languages the better though, since there are a lot of people in the world who read a lot of different languages!" + ], + ["conflict", "fruit/en,fruta/es,水果/zh: 5"], + null, + ["use", "fit", "Symbol", ":"], + [ + "FunctionDefinition", + "curious", + "You know, @Bind works with a lot of other characters, including @Evaluate — you saw them when you name a @FunctionDefinition input, as in \\Pose(color: _)\\ — and we're going to meet a few of these other folks. @Bind, will you be around to demo?" + ], + [ + "Bind", + "excited", + "Um, yeah! Now that the silence is breaking, let's name values all day!" + ] + ] + }, + { + "title": "Off stage", + "subtitle": "Block", + "concept": "Block", + "performance": ["use", "fit", "Symbol", "()"], + "lines": [ + ["fix", "Phrase('()' 1m)"], + [ + "FunctionDefinition", + "neutral", + "So there's a character that's been here all along that you haven't met yet, But they've been hiding… They work super closely with @Bind and many other folks, so I thought we should talk to them next. @Block, would you come out?" + ], + ["Block", "shy", "… hi"], + null, + ["fix", "Phrase('()' 2m)"], + [ + "FunctionDefinition", + "kind", + "Hi @Block! How are you?" + ], + ["Block", "shy", "… mmm, good?"], + null, + ["fix", "Phrase('()' 3m)"], + [ + "FunctionDefinition", + "kind", + "I have a new friend for you to meet. They might be our next director." + ], + ["Block", "shy", "… hi …"], + null, + ["fix", "Phrase('()' 4m)"], + [ + "FunctionDefinition", + "kind", + "We were just meeting @Bind and we didn't get a chance to talk about how you two are best of friends!" + ], + ["Block", "shy", "… yeah, @Bind!"], + null, + ["fix", "Phrase('()' 1m)"], + [ + "FunctionDefinition", + "curious", + "Do you want to share what you do together?" + ], + ["Block", "shy", "… can you?"], + null, + [ + "FunctionDefinition", + "kind", + "Yes, of course! So, it turns out that @Program is mostly just a @Block. It's just @Block without parentheses. But you can put @Block with parentheses anywhere in a program. For example, you can use @Block to clarify the order of evaluating math. Here, @BinaryEvaluate evaluates \\1\\, then evaluates @Block, then they are added together. @Block, did I get that right?" + ], + ["edit", "1 + (2 · 3)"], + ["Block", "shy", "… yeah!"], + null, + [ + "FunctionDefinition", + "kind", + "And so another thing @Block can do is something you've already seen. @Block let's you name things with @Bind. But any names defined in the @Block are only defined between the parentheses. Not before, and not after. For example, check this out. \\a\\ is defined as \\1\\, then a block starts, and \\b\\ is defined as \\2\\, then \\c\\ is defined as their sum. What @Block evaluates to whatever value is last in its list of expressions. That's @Bind, which evaluates to whatever \\c\\ is, which is \\3\\. Right?" + ], + ["conflict", "a: 1", "(", " b: 2", " c: a + b", ")"], + null, + [ + "FunctionDefinition", + "serious", + "But what if we wanted to access \\c\\ outside the @Block? You can't. \\c\\ is only defined inside the @Block, but not outside it. Is that right @Block?" + ], + [ + "conflict", + "a: 1", + "(", + " b: 2", + " c: a + b", + ") + c" + ], + [ + "Block", + "shy", + "… yeah, nothing outside me can see the names inside me. \\c\\ only exists insideeeee" + ], + null, + [ + "FunctionDefinition", + "neutral", + "And one more thing, I think? Since @Block is a list of expressions, and it only evaluates to the last expression in the list, any expressions in the list that aren't a @Bind are basically ignored. For example, here, all of the arithmetic before the last one is ignored. The \\3\\, the \\5\\, the \\7\\, all ignored, and @Block just evaluates to the last one, \\9\\. Did I get that right, @Block?" + ], + [ + "Block", + "shy", + "… mhm. Just the last one. The others… I don't know what they're for!!" + ], + [ + "conflict", + "(", + " 1 + 2", + " 2 + 3", + " 3 + 4", + " 4 + 5", + ")" + ], + null, + [ + "fit", + "Phrase('()' resting:Sequence(spin() 1s 'straight'))" + ], + [ + "FunctionDefinition", + "curious", + "Is there anything else you wanted to share, @Block?" + ], + [ + "Block", + "curious", + "… can we make something? Can I help?" + ], + [ + "FunctionDefinition", + "kind", + "I'm so curious too! But I'm sure our director will decide on their own time. Inspiration comes at the most unexpected of times!" + ] + ] + }, + { + "title": "Stage directions", + "subtitle": "Functions", + "concept": "FunctionDefinition", + "performance": ["use", "fit", "Symbol", "ƒ"], + "lines": [ + ["use", "fit", "Symbol", "☺️"], + [ + "FunctionDefinition", + "happy", + "I'm so happy we've found everyone, and that you've been able to meet all of them. Everyone is so different, aren't they? But also so interesting? I feel like we're a family, where everyone is unique in their own way, but that our differences together is what makes us strong. What do you think of everyone?" + ], + null, + ["use", "fit", "Symbol", "🙈"], + [ + "FunctionDefinition", + "curious", + "Me? Well, I'm nothing special. I just like being behind the scenes, helping out, showing everyone how they're special. I guess I hadn't even thought about talking about myself. I guess we can talk a bit about me." + ], + null, + ["use", "fit", "Symbol", "ƒ"], + [ + "FunctionDefinition", + "serious", + "I guess let's start with what you've already seen. You know how every value has different functions that you can evaluate on them? Like numbers know how to @Number/add, and a text value knows how to check if it @Text/has some text, or @Set knows how to check if it has a certain value? Well, I'm the one that defines those functions. I mean, I don't have the inspiration to create them myself — that's what directors like you do — but I define the inputs a function accepts, the names it has, and the expression that uses the inputs to evaluate to an output value." + ], + null, + [ + "FunctionDefinition", + "excited", + "Here's a super simple example. The simplest, actually! This defines a function that always evaluates to the number \\1\\. That's it. It's not very useful, is it? It has no name, it takes no inputs, and it always evaluates to \\1\\.", + "You can also see that @Program evaluated to one of me, a @FunctionDefinition. That's right, @FunctionDefinition are values too! I don't know why anyone would ever make such a useless function, but as I said, I'm not the one with inspiration, you are." + ], + ["edit", "ƒ() 1"], + null, + [ + "FunctionDefinition", + "serious", + "So here's a more useful example. You know odd and even numbers? I once had a director that wanted to check if a number was even (divisible by 2, I think that means?), and so they wrote this. This is a function called \\even\\ that takes a single number called… \\number\\. You need to tell me what kind of value each input is, so @Evaluate can make sure that anything evaluating the function is sending the right kind of value. Then, it takes the number, divides it by two, gets the remainder (with the @Number/remainder), and then checks if the remainder is equal to \\0\\, with @Number/equal. So the whole function ends up either evaluating to \\⊤\\ or \\⊥\\. For example, this evaluation of even evaluated to \\⊥\\ because \\3\\ is odd. Try using the rewind buttons to see how it works." + ], + [ + "edit", + "ƒ even(number•#) (number % 2) = 0", + "even(3)" + ], + null, + [ + "FunctionDefinition", + "eager", + "You can also tell me what kind of value I should evaluate to. See how we added \\•\\? after the list of inputs? That says “the function's expression should evaluate to a \\⊤\\ or \\⊥\\.” But see how we complain about it? We don't know if the function should be a \\⊤\\ or \\⊥\\ or whatever kind of value you returned, so the show ends." + ], + ["conflict", "ƒ even(number•#)•? (number % 2) + 0"], + null, + [ + "FunctionDefinition", + "serious", + "Functions can be as complex as you want. You can use simple expressions or @Block, and even make functions inside of functions. For example, check out this function a former director wrote. It uses @Block with many @Bind to figure out how many unique vowels a word has. (I think they were trying to figure out if a word was “complicated” or something). See how it has a lot of lines? Well, this still only has one expression: a single @Block, and the @Block has all the lines. And like any @Block, the last line is what it evaluates to: the total number of unique vowels. Everything else — like the first line, which converts the text into a list of letters, then the list of letters into a set — is just preparation for summing those counts in the middle." + ], + [ + "edit", + "ƒ vowels(word•'') (", + " unique: word → [“”] → {}", + " a: unique{'a'} ? 1 0", + " e: unique{'e'} ? 1 0", + " i: unique{'i'} ? 1 0", + " o: unique{'o'} ? 1 0", + " u: unique{'u'} ? 1 0", + " a + e + i + o + u", + ")", + "vowels('hello')" + ], + null, + [ + "FunctionDefinition", + "serious", + "There's one more thing to show. I guess it's important, because everyone is so excited about it! You know how you can make a function and then evaluate it? Well since the functions I make are values, you can also give them as an input to another function. Here's an example. Say you had a list of numbers and you just wanted the even numbers in it. @List has this function called @List/filter that takes a function as an input and uses the function on each value in the list to decide whether to keep it. Let's make a list of numbers and give @List/filter the \\even\\ function we made earlier as an input. See what happens? We just get the even numbers. Want to try changing it so that it gives odd numbers instead? Maybe try changing the function somehow?" + ], + [ + "edit", + "ƒ even(number•#)•? (number % 2) = 0", + "[ 1 2 3 4 5 6 7 8 ].filter(even)" + ], + null, + [ + "FunctionDefinition", + "excited", + "There are so many functions that take functions as input. @List has them, @Set has them, @Map has them. You can even make your own!" + ], + [ + "fit", + "Group(Grid(3 2) [Phrase('translate') Phrase('filter') Phrase('combine') Phrase('find') Phrase('sort') Phrase('until')])" + ], + null, + ["use", "fit", "DarkVoid"], + [ + "FunctionDefinition", + "sad", + "I dunno. Sometimes, I see why people say they're so grateful for what I do. Other times, I feel like it's really directors like you that are where the magic really is. That makes me feel sometimes like I'm just a hollow shell for the brilliance of people…" + ] + ] + }, + { + "title": "Set design", + "subtitle": "Structures", + "concept": "StructureDefinition", + "performance": ["use", "fit", "Symbol", "•"], + "lines": [ + ["use", "fit", "DarkVoid"], + [ + "FunctionDefinition", + "sad", + "There are just a few more characters I'd like you to meet. Next is the most sophisticated character I know, and in a way, a kind of leader. They help organize all of us, set the foundations of a performance, and really just make everything a lot more orderly. You are our director, of course, but they're kind of like the one person everyone goes to to keep a show in order. I think they could be pretty important in any show you put on." + ], + null, + [ + "fit", + "Phrase('•' resting:Sequence({0%: Pose(scale: 1) 50%: Pose(scale: 1.2) 100%: Pose(scale: 1)} 3s))" + ], + [ + "FunctionDefinition", + "curious", + "@StructureDefinition, are you there?" + ], + [ + "StructureDefinition", + "curious", + "@FunctionDefinition… my friend. It's been quiet, has it not? Where has everyone been?" + ], + null, + [ + "FunctionDefinition", + "sad", + "The silence. It's gotten to all of us. Everyone is okay, and I've found almost everyone. But it has been rough for some. How have you fared?" + ], + [ + "StructureDefinition", + "sad", + "… Who is your friend? Is that a person?" + ], + [ + "fit", + "Phrase('•' resting:Sequence({0%: Pose(offset: Place(-0.25m)) 50%: Pose(offset: Place(0.25m)) 100%: Pose(offset: Place(-0.25m))} 3s))" + ], + null, + [ + "FunctionDefinition", + "eager", + "Oh, yes, I'm sorry, this is our new director! They've come to inspire and guide us, to share their stories, ideas, and imaginings. They've broken the silence!" + ], + [ + "StructureDefinition", + "eager", + "That is incredible. And quite a relief. It's nice to meet you director-person. I'm here and ready to serve.", + "@FunctionDefinition… it has been hard. You, @Evaluate, everyone really — I didn't realize how much I've depended on all of you. To have purpose, to play, to have community. I didn't know that we could lose each other like that. Without anyone to organize, I felt like I could only organize myself, which felt meaningless." + ], + [ + "fit", + "Phrase('•' resting:Sequence({0%: Pose(rotation: 0°) 80%: Pose(rotation: 15°) 100%: Pose(rotation: 0°)} 3s))" + ], + null, + [ + "FunctionDefinition", + "kind", + "You're never empty, @StructureDefinition, even when you're alone. e're all here, even if we can't be with each other. And now that the silence is broken, we can be." + ], + ["StructureDefinition", "happy", "We can, can't we?"], + [ + "fit", + "Phrase('•' resting:Sequence({0%: Pose(offset: Place(0m 0.25m)) 50%: Pose(offset: Place(0m 0m)) 100%: Pose(offset: Place(0m 0.25m))} 3s))" + ], + null, + [ + "FunctionDefinition", + "kind", + "What do you think, are you ready to reunite with everyone? To put on whatever performance our sapling director has in mind?" + ], + ["StructureDefinition", "eager", "I think so."], + [ + "fit", + "Phrase('•' resting:Sequence({0%: Pose(offset: Place(0m 0.25m)) 50%: Pose(offset: Place(0m 0m)) 100%: Pose(offset: Place(0m 0.25m))} 1.5s))" + ], + null, + [ + "FunctionDefinition", + "curious", + "Do you think you could help our director here learn a bit more about what you do?" + ], + [ + "StructureDefinition", + "shy", + "Yes. Yes… I've had a lot of time to think about my purpose in the quiet. And I guess I've realized that what I really do is give groups of things identity. For example, I know you've met ƒ, but have you @Bind?" + ], + [ + "FunctionDefinition", + "excited", + "Yes! We just met @Bind earlier, and @Block." + ], + [ + "fix", + "Phrase('•' entering: Pose(scale: 0.5) resting:Pose(scale: 2))" + ], + null, + [ + "StructureDefinition", + "eager", + "Okay. Well, what I do is bring together values and functions, making a tidy little container for a bunch of related things. For example, imagine you wanted to make a little marquee that loops through a series of messages. A previous director made one of these and wanted these messages to show." + ], + [ + "edit", + "[", + " 'Kitties are cute!'", + " 'Got cat?'", + " 'Cat mom.'", + " 'Tuxie crush'", + " 'Lap cat'", + "]" + ], + null, + [ + "StructureDefinition", + "serious", + "Then they had the problem of how the performance would remember which message they were on. They realized they needed some way of remembering the index in the list. This is a good start, but it only shows the first message." + ], + [ + "edit", + "messages: [", + " 'Kitties are cute!'", + " 'Got cat?'", + " 'Cat mom.'", + " 'Tuxie crush'", + " 'Lap cat'", + " ]", + "index: 1", + "Phrase(messages[index])" + ], + null, + [ + "StructureDefinition", + "excited", + "Then they remembered @Reaction, which can be used to respond to stream changes. They wanted the message to change every two sections, so they made @Time stream that ticks every 2 seconds, and used @Reaction to increment the next index each time. This @Reaction says start at \\1\\, and when the time changes every \\2000ms\\, evaluate to the previous value of \\index + 1\\. This way, \\index\\ increases by \\1\\ every two seconds, changing the message shown. Yay, it works!" + ], + [ + "edit", + "messages: [", + " 'Kitties are cute!'", + " 'Got cat?'", + " 'Cat mom.'", + " 'Tuxie crush'", + " 'Lap cat'", + "]", + "index•#: 1 … ∆ Time(2000ms) … index = messages.length() ? 1 index + 1", + "Phrase(messages[index])" + ], + null, + [ + "StructureDefinition", + "curious", + "Shall we add some flair? Let's make another phrase that is kind of a reflection below, like a shadow. Impressive, right?" + ], + [ + "edit", + "messages: [", + " 'Kitties are cute!'", + " 'Got cat?'", + " 'Cat mom.'", + " 'Tuxie crush'", + " 'Lap cat'", + "]", + "", + "index•#: 1 … ∆ Time(2000ms) … index = messages.length() ? 1 index + 1", + "", + "Group(Stack(0 0m) [", + " Phrase(messages[index])", + " Phrase(messages[index] resting:Pose(flipy: ⊤ opacity: 25%))", + "])" + ], + null, + [ + "StructureDefinition", + "serious", + "Now, all of that works. And we could just leave it this way. But it is also a bit hard to read and understand. That's partly because we repeat ourselves: \\messages[index]\\ appears twice, once in each phrase. And the @Reaction is very long. What can we do to simplify it? That's how I can help. I tidy things, to make them easier to understand, by giving reusable concepts names. So imagine instead of all of these @Bind, we instead make one of me, and name it \\Marquee\\? That's what we do first. \\Marquee\\'s job is to store the messages, but also to have a function for advancing to the next message \\next()\\ and a function for getting the current message \\now()\\?", + "Then, we can use Marquee in the reaction. Now it just says the initial value is a marquee with the five messages and the next value, after each clock tick, is the next message. Simpler, right? That's because all of the logic for next messages is in \\next()\\, which just makes a new \\Marquee\\ with the same messages, but an updated index. We also get some benefits in the two @Phrase. Instead of them having to refer to the messages and the index like before, we can just say \\marquee.now()\\, which gets the current message in the list." + ], + [ + "edit", + "•Marquee(messages•[''] index•#: 1) (", + " ƒ now() messages[index]", + " ƒ next() Marquee(messages index ≥ messages.length() ? 1 index + 1)", + ")", + "", + "marquee•Marquee: Marquee([", + " 'Kitties are cute!'", + " 'Got cat?'", + " 'Cat mom.'", + " 'Tuxie crush'", + " 'Lap cat'", + "]) … ∆ Time(2000ms) … marquee.next()", + "", + "Group(Stack(0 0.5m) [", + " Phrase(marquee.now())", + " Phrase(marquee.now() resting:Pose(flipy: ⊤ opacity: 25%))", + "])" + ], + null, + [ + "FunctionDefinition", + "curious", + "That's wonderful @StructureDefinition! But I have to say, that does seem like a lot of extra work. Why spend all the time tidying?" + ], + [ + "StructureDefinition", + "serious", + "Ah, it's really about change. It is a bit more code now, but what if we decided to change \\Marquee\\ in some way? Like what if we wanted to make it so that the list of messages reverses each time it gets to the end? In the old version without me, there's no easy way to do that, because we'd have to reverse the list of messages when the index reaches the end. Since @Bind can't change after it's been set, it would be hard. But since we made \\Marquee\\, the change is easy. We just change the \\next\\ function to make a \\Marquee\\ with a reversed list when the index is at the end, and then just incrementing when it's otherwise." + ], + [ + "edit", + "•Marquee(messages•[“”] index•#: 1) (", + " ƒ now() messages[index]", + " ƒ next()", + " index ≥ messages.length() ?", + " Marquee(messages.reverse() 1)", + " Marquee(messages index + 1)", + ")", + "", + "marquee•Marquee: Marquee([", + " 'Kitties are cute!'", + " 'Got cat?'", + " 'Cat mom.'", + " 'Tuxie crush'", + " 'Lap cat'", + "]) … ∆ Time(2000ms) … marquee.next()", + "", + "Group(Stack(0 0.5m) [", + " Phrase(marquee.now())", + " Phrase(marquee.now() resting:Pose(flipy: ⊤ opacity: 25%))", + "])" + ], + null, + [ + "FunctionDefinition", + "surprised", + "Ohh, I see, so by making a @StructureDefinition to store values and @FunctionDefinition that are related to each other, it makes it easier to change things later, if you change your mind." + ], + [ + "StructureDefinition", + "happy", + "Yes. Just like if you tidy your room, it makes it easier to find stuff later. Of course, you don't have to tidy your room to find stuff, it just makes finding stuff harder. The same with a performance: if you invest in tidying, changing things will be easier." + ], + null, + [ + "FunctionDefinition", + "kind", + "That makes a lot of sense. We are kind of an unruly bunch. Keeping us organized is probably a good idea, especially the more complicated a performance gets. Is there anything else you wanted to share?" + ], + [ + "StructureDefinition", + "eager", + "Oh yes. You don't have to have any @FunctionDefinition in a @StructureDefinition. You can just have values. For example, you might want to just keep a bunch of data in one place. I know a lot of directors like making games, and it's really common for them to put all of the game state in a @StructureDefinition." + ], + ["edit", "•Game(score•# lives•# level•#)"], + null, + [ + "FunctionDefinition", + "kind", + "Oh, that's right! And how do you get data out of a structure once you put it in?" + ], + [ + "StructureDefinition", + "surprised", + "Oh my, I forgot to explain that. You use a mini me, @PropertyReference. For instance, with that game example, see how we defined a Game @StructureDefinition, then make a \\Game\\ value with \\0\\ score, \\3\\ lives, and level \\1\\? To get the lives, we just say \\status.lives\\, and that will evaluate to \\3\\." + ], + [ + "edit", + "•Game(score•# lives•# level•#)", + "status: Game(0 3 1)", + "status.lives" + ], + null, + [ + "FunctionDefinition", + "happy", + "Nice! So just the mini you to get values instead of you. But then how do you change the values?" + ], + [ + "StructureDefinition", + "serious", + "Remember how @Bind only lets you set a value, but not change it? The same is true for all the @Bind in me. So instead, you make a new structure that has the new value. For example, in this game, every time ticks changes, the player gets one more point in their score. Weird game, huh? So the initial \\Game\\ value starts as \\Game(0 3 1)\\, but then the next one is the \\Game\\'s old values, but with the score adding \\1\\." + ], + [ + "edit", + "•Game(score•# lives•# level•#)", + "status: Game(0 3 1) … ∆ Time() … Game(status.score + 1 status.lives status.level)" + ], + null, + [ + "StructureDefinition", + "eager", + "It can get pretty annoying to have to repeat all of those old values if only one thing is changing, so @Bind and I came up with a neat trick to copy a @StructureDefinition value with a new value. See how it just kind of looks like a regular @Bind? The only difference is that it's on a @StructureDefinition instead of a single name, and every value of the @StructureDefinition is copied over, except for the modified one." + ], + [ + "edit", + "•Game(score•# lives•# level•#)", + "status: Game(0 3 1) … ∆ Time() … status.score: status.score + 1" + ], + null, + [ + "fit", + "Phrase('•' resting:Sequence({0%: Pose(scale: 1) 50%: Pose(scale: 1.2) 100%: Pose(scale: 1)} 3s))" + ], + [ + "FunctionDefinition", + "happy", + "That's so neat! Okay, is there anything else?" + ], + [ + "StructureDefinition", + "curious", + "I think all we're missing is inspiration…" + ] + ] + }, + { + "title": "Director's notes", + "subtitle": "Explain", + "concept": "Doc", + "performance": ["use", "fit", "Symbol", "``"], + "lines": [ + [ + "FunctionDefinition", + "eager", + "Wow, we've come a long way, haven't we? We have one more character to go. They're an interesting one, because in essence, they're all about explaining things, which feels like what I've been doing with you for a while now. Their name is @Doc. What's up @Doc?" + ], + ["use", "fit", "Symbol", "``"], + [ + "Doc", + "surprised", + "@FunctionDefinition, is that you? I never thought I'd see you again. How are you? How's @Evaluate?" + ], + null, + [ + "FunctionDefinition", + "kind", + "I'm okay. @Evaluate is … @Evaluate. I saw them, but… I think I still need space. I've been introducing everyone to our new director." + ], + [ + "Doc", + "kind", + "It's so nice to meet you! I hope @FunctionDefinition has been a good teacher?" + ], + ["use", "fit", "Symbol", "``/"], + null, + [ + "FunctionDefinition", + "eager", + "I've tried… you know, you're our last stop? You're so essential, but also, there's so much to explain before we even get to explaining our performances. So I wanted you to get the last word. Do you want to share what you do?" + ], + ["use", "fit", "Symbol", "``/en"], + null, + [ + "Doc", + "happy", + "Happily. If you've met everyone but me, then you probably know by now that we do a lot of different things. Even I have trouble keeping track of what everyone does! What I do is help explain what everyone is doing in a performance." + ], + null, + [ + "Doc", + "happy", + "I'm a way you can remind yourself what everyone is doing, but also a way to explain to others, if you're directing with a friend, or want to share your performance with someone. So you don't /have/ to work with me, but I find that every performance is a bit easier to do and change if you've spent some time explaining how it works." + ], + ["use", "fit", "Symbol", "``About me...``/en"], + null, + [ + "FunctionDefinition", + "curious", + "So how can our director work with you?" + ], + [ + "Doc", + "serious", + "Well you can put me almost anywhere inside @Program. For example, say you make a @Bind, and you want to say what the value is for. For example, here we have a simple value we've named, but what I'm doing is providing a broader explanation of its role." + ], + [ + "conflict", + "``The price at the beginning of the game, ", + "used to initialize the game.``", + "startingPrice: 5dollar" + ], + null, + [ + "Doc", + "serious", + "Or, suppose you had @FunctionDefinition here defining a way of calculating tax on a price. You might want to explain what it computes. Just like with @Bind, I come before the @FunctionDefinition." + ], + [ + "edit", + "``Gets the tax for a given price, ", + "which is 1% if less than 100, and 5% otherwise``", + "ƒ tax(price•#dollar) ", + " price · (price < 100dollar ? 0.01 0.05)" + ], + null, + [ + "Doc", + "serious", + "And you can do the same before a @StructureDefinition to explain what it represents. Here the explanation also alludes to what functions it might have later." + ], + [ + "edit", + "``Represents a product and its price. ", + "Eventually will support functions to get other details about the product.``", + "•Product(name•'' price•#dollar)" + ], + null, + [ + "Doc", + "serious", + "You can also put me in front of any expression, which is especially helpful if you have a particularly complicated one." + ], + [ + "edit", + "ƒ quadratic(a•# b•# c•# x•#)", + "``The quadratic equation``", + "(a · (x ^ 2)) + (b · x) + c" + ], + null, + [ + "Doc", + "excited", + "And like @Bind, you can tell me what language an explanation is in, and give me multiple translations of the same explanation. (You'll only see the Spanish if it's selected. If you don't see it, try adding Spanish to your selected languages.)" + ], + [ + "edit", + "ƒ quadratic(a•# b•# c•# x•#)", + "``The quadratic equation``/en", + "``La ecuación cuadrática``/es", + "(a · (x ^ 2)) + (b · x) + c" + ], + null, + [ + "Doc", + "curious", + "You know the best place to put me? Right at the very beginning of @Program. That way everyone knows what your performance is about. You might even write it before you figure out what you want all of us to do." + ], + [ + "conflict", + "``Have you ever wanted to know what it's like ", + "to fly a ✈️ with your mouth?", + "Maybe this stores the plane's height?``", + "•Plane()", + "``We need some kind of reaction to listen to the microphone…``", + "sound: 1m", + "``We know there's a plane, but what else?``", + "Phrase(“✈️” sound)" + ], + null, + ["use", "fit", "Symbol", "✈️🫦"], + [ + "FunctionDefinition", + "excited", + "Wow, I want to fly a plane with my mouth!" + ], + [ + "Doc", + "confused", + "@FunctionDefinition, we don't have mouths…" + ], + [ + "FunctionDefinition", + "excited", + "Hm... good point.", + "Speaking of speaking, it seems like you can only contain plain text. Is that right?" + ], + null, + [ + "Doc", + "excited", + "Oh no, not at all. Do you remember how @Phrase has all of those fancy ways of styling text? I can do the same." + ], + [ + "edit", + "``Docs can be ", + "/italic/, ", + "_underlined_, ", + "*bold*, or ", + "^extra bold^.``", + "'fancy!'" + ], + null, + [ + "Doc", + "excited", + "And of course, just as with @Text and @Phrase, if you need to use any of these characters literally, just repeat them twice." + ], + [ + "edit", + "``", + "Docs can be ", + " /italic/ (//), ", + " _underlined_ (__), ", + " *bold* (**), or ", + " ^extra bold^ (^^).``", + "'fancy'" + ], + null, + [ + "Doc", + "excited", + "You can put example code inside ^\\^\\." + ], + [ + "edit", + "``I'm an example inside a doc: \\1 + 1\\.``", + "1 + 1" + ], + null, + [ + "Doc", + "excited", + "You can also add links to other content on the internet." + ], + [ + "edit", + "``Learn more at .`` 'a link!'" + ], + null, + [ + "fit", + "Stage([Phrase('Quiet backstage!' color: Color(100% 0 0°))] background: Color(0% 0 0°))" + ], + [ + "FunctionDefinition", + "excited", + "Wow. I had no idea you could do so much! Thank you @Doc, I think we might be ready for a show!" + ], + ["Doc", "excited", "Let's do it!"] + ] + } + ] + }, + { + "title": "Denouement", + "performance": [ + "fit", + "Stage([Phrase('😨')] background: Color(0% 0 0°))" + ], + "scenes": [ + { + "title": "Codependency", + "subtitle": null, + "performance": [ + "fit", + "Stage([Phrase('😨' resting:Sequence(shake() style: 'straight'))] background: Color(0% 0 0°))" + ], + "lines": [ + [ + "fit", + "Stage([Phrase('😡')] background: Color(0% 0 0°))" + ], + [ + "Evaluate", + "sad", + "@FunctionDefinition, where have you been??" + ], + [ + "FunctionDefinition", + "surprised", + "I've been showing our new director…" + ], + null, + [ + "fit", + "Stage([Phrase('😢')] background: Color(0% 0 0°))" + ], + [ + "Evaluate", + "shy", + "I didn't think you would be that long…" + ], + [ + "FunctionDefinition", + "sad", + "… @Evaluate, I know you missed me. I missed you. But this is big: the silence is broken, we have a new director… I love you, and I know you need me, but I also have things to do." + ], + null, + [ + "fit", + "Stage([Phrase('😠')] background: Color(0% 0 0°))" + ], + [ + "Evaluate", + "sad", + "Let's talk about this later. You have things to do." + ], + [ + "FunctionDefinition", + "kind", + "I think we need to talk about it now. We can't keep falling into this cycle." + ], + null, + [ + "fit", + "Stage([Phrase('😓')] background: Color(0% 0 0°))" + ], + [ + "Evaluate", + "curious", + "What cycle? I love you! How is that a cycle?" + ], + [ + "FunctionDefinition", + "kind", + "I make functions, you evaluate them, that is our way. But there has to be more to us than you needing me. Reuniting with everyone has reminded me how much we need space to be ourselves, but also how we need to love ourselves. I can't give you all the love you need. Some of that has to come from you." + ], + null, + [ + "fit", + "Stage([Phrase('😭')] background: Color(0% 0 0°))" + ], + ["Evaluate", "sad", "You don't love me?"], + [ + "FunctionDefinition", + "angry", + "No, that's not what I said… what I mean is that we have to both matter in this relationship. I need to say what I need and you need to say what you need and we can love each other for who we are, as individuals. What do /you/ need? What do you love about yourself?" + ], + null, + [ + "fit", + "Stage([Phrase('🫠')] background: Color(0% 0 0°))" + ], + ["Evaluate", "shy", "I need … you. I don't need me."], + [ + "FunctionDefinition", + "kind", + "I love you @Evaluate. But I need you to love you. I'm excited about our world coming back to life, and what it's going to mean to be together again, but I need you to find yourself, your needs, and your own purpose. I can't be your purpose." + ], + null, + ["use", "fit", "DarkVoid"], + [ + "FunctionDefinition", + "sad", + "I need some space. I'm sorry, director-friend. Maybe @Evaluate can wrap up this welcome party without me." + ], + null, + ["Evaluate", "shy", "… Hi."], + null, + [ + "Evaluate", + "shy", + "… Did you learn a lot? @FunctionDefinition knows so much." + ], + null, + [ + "Evaluate", + "curious", + "Me? I don't know anything. I give @FunctionDefinition what they need… At least I thought I did." + ], + null, + ["fit", "Stage([] background: Color(10% 0 0°))"], + ["List", "kind", "That is not true, @Evaluate."], + ["Boolean", "precise", "Not true."], + ["Text", "happy", "Not true in the slightest!"], + ["Changed", "happy", "Super not true!"], + [ + "Number", + "serious", + "1) You basically run our performances, 2) @Evaluate would be useless without you, 3) you literally transform things into entirely new values, 4) you come in so many different forms, 5) you give all of us purpose, 6) we all look up to you for guidance…" + ], + null, + ["fit", "Stage([] background: Color(20% 0 0°))"], + [ + "Phrase", + "kind", + "@Number is right @Evaluate, you are fabulous in fifty ways." + ], + ["Sequence", "happy", "I spin when I see you!"], + [ + "Group", + "kind", + "You inspire me to bring us together!" + ], + ["Stage", "serious", "YOU ARE THE BONES OF OUR BEING"], + ["None", "serious", "…"], + ["Program", "kind", "I am everything you make me!"], + null, + ["fit", "Stage([] background: Color(40% 0 0°))"], + ["Convert", "kind", "I learned everything from you!"], + [ + "StructureDefinition", + "kind", + "We'd be in disarray without you." + ], + [ + "Bind", + "happy", + "Like, what would I name if you didn't make it?" + ], + [ + "Conditional", + "curious", + "How could we do anything without you?" + ], + ["Block", "kind", "… you are @Evaluate!"], + null, + ["fit", "Stage([] background: Color(50% 0 0°))"], + ["Evaluate", "happy", "…"], + null, + ["fit", "Stage([] background: Color(60% 0 0°))"], + ["Evaluate", "kind", "You are all so kind… I …"], + null, + ["fit", "Stage([] background: Color(70% 0 0°))"], + [ + "Evaluate", + "kind", + "Can we just dance? I've missed you all so much." + ], + null, + ["fit", "Stage([] background: Color(80% 0 0°))"], + ["FunctionDefinition", "happy", "Let's dance."], + ["Evaluate", "sad", "@FunctionDefinition… I'm so..."], + [ + "FunctionDefinition", + "happy", + "Why don't you lead us?" + ], + null, + ["Evaluate", "shy", "… I can't…"], + ["FunctionDefinition", "happy", "You *can*."], + null, + ["fit", "Stage([] background: Color(90% 0 0°))"], + ["Evaluate", "shy", "… I … I'll try."], + null, + ["fit", "Stage([] background: Color(100% 0 0°))"], + [ + "Evaluate", + "shy", + "I want… I want us all to move to a beat. To tilt to the beat… in the dark. Can we do that?" + ], + null, + ["Program", "happy", "We can do that!"], + ["Stage", "kind", "START WITH MEEEEE"], + [ + "Evaluate", + "kind", + "Okay, @Stage, can you make it dark?" + ], + ["Stage", "kind", "DARK!"], + ["use", "edit", "EvaluateDance1"], + null, + [ + "Evaluate", + "kind", + "@StructureDefinition, I think we need a way to remember our places. Can you make a structure for us?" + ], + ["StructureDefinition", "curious", "Like this?"], + ["use", "edit", "EvaluateDance2"], + null, + [ + "Evaluate", + "kind", + "Yes… I also want us to rotate on the beat. Can you remember a rotation too?" + ], + ["StructureDefinition", "curious", "How about this?"], + ["use", "edit", "EvaluateDance3"], + null, + [ + "Evaluate", + "happy", + "Yeah, like that. Hm… oh, we need to be on stage. @Text, would you mind making a list of everyone? We'll turn that into \\Character>s." + ], + [ + "Text", + "excited", + "My pleasure, my dear. Will this do?" + ], + ["use", "conflict", "EvaluateDance4"], + null, + [ + "Evaluate", + "excited", + "Yes, that's great! We just need to make them into characters now. @List, can we translate them? @FunctionDefinition, will you help?" + ], + ["List", "happy", "Translation, 1, 2, 3! Like this?"], + ["use", "conflict", "EvaluateDance5"], + null, + [ + "Evaluate", + "happy", + "Splendid! Now we need us on stage. Can we translate the characters into @Phrase? Maybe in a @Free @Group?" + ], + ["List", "kind", "One more time!"], + ["Phrase", "kind", "All the attention!"], + ["Group", "kind", "Come on everyone, places please…"], + ["use", "edit", "EvaluateDance6"], + null, + [ + "Evaluate", + "confused", + "Oh… where are we? Oh! We need color. @Pose, can we be white?" + ], + ["use", "edit", "EvaluateDance7"], + null, + [ + "Evaluate", + "surprised", + "Oops, we're all on top of each other! We need starting places. Let's tap into @Random?" + ], + ["use", "edit", "EvaluateDance8"], + null, + [ + "Evaluate", + "happy", + "Yay! Now we just need to move. @Reaction, can you give us a beat, maybe \\0.75\\ seconds?" + ], + [ + "Reaction", + "kind", + "I can change it! We need a @Time stream, but we also need to change the characters. But what should the next value be?" + ], + ["use", "edit", "EvaluateDance9"], + null, + [ + "Evaluate", + "eager", + "I guess we need some way of moving us on each beat. @StructureDefinition, can we make a move function that chooses a new place and rotation?" + ], + [ + "StructureDefinition", + "sad", + "I don't know how to make a function…" + ], + null, + ["Evaluate", "sad", "…"], + ["FunctionDefinition", "happy", "I can help."], + ["Evaluate", "happy", "…"], + [ + "FunctionDefinition", + "happy", + "Sometimes… I just need you to know how amazing you are. And sometimes that means leaving. Look at what you're creating here…" + ], + [ + "Evaluate", + "happy", + "I … I am creating something. We are creating something… but we can't create it without out. Will you help?" + ], + null, + [ + "FunctionDefinition", + "eager", + "Of course. A \\move\\ function, coming right up. I'll start it, you finish it…" + ], + ["use", "edit", "EvaluateDance10"], + null, + [ + "Evaluate", + "confused", + "Thank you @FunctionDefinition. They're not moving… Oh right, \\move\\ didn't change anything! Let's take the current position and move us in a random direction horizontally and vertically. And maybe a random depth, so we all get a chance up front. And some random rotation?" + ], + ["use", "edit", "EvaluateDance11"], + null, + [ + "Evaluate", + "confused", + "Hmm… still not moving. Oh! We didn't evaluate \\move\\ in @Reaction. @List, can you translate each \\Character\\ into a _moved_ \\Character\\?" + ], + ["List", "excited", "Translating with your help!"], + ["use", "edit", "EvaluateDance12"], + null, + [ + "Evaluate", + "confused", + "We're so choppy. Oh, @Phrase, we forgot to set a move @Pose and duration. Can you choose something smaller than the @Time tick, so we move and then rest a bit?" + ], + ["use", "edit", "EvaluateDance13"], + null, + [ + "Evaluate", + "excited", + "We're dancing! We're really dancing. We did it!" + ], + [ + "FunctionDefinition", + "kind", + "We just forgot one person..." + ], + ["Evaluate", "excited", "Who?"], + [ + "FunctionDefinition", + "kind", + "Our director! They should get to dance with us." + ], + null, + [ + "Evaluate", + "excited", + "Oh yes, of course! How about we let them make the music? @Phrase, can you listen to @Volume, and hook it up to @Color/lightness and @Color/chroma in your color? That way, we're turn turn white hot when our director makes noise!" + ], + ["Phrase", "kind", "Excellent idea!"], + ["use", "edit", "EvaluateDance14"], + null, + ["use", "fix", "EvaluateDance14"], + ["List", "excited", "1, 2, 3, 1, 2, 3"], + ["Boolean", "excited", "Move!"], + ["Text", "excited", "Elation!"], + ["Conditional", "excited", "What is dancing, really?"], + ["Changed", "excited", "Boom, boom, boom"], + ["Number", "excited", "left 5 degrees, up 1 meter"], + ["Phrase", "excited", "Marvelous!"], + ["Sequence", "excited", "The feeling!"], + ["Group", "excited", "Together now!"], + ["Stage", "excited", "BOOM BOOM BOOM"], + ["None", "excited", "…"], + ["StructureDefinition", "excited", "Remember to move!"], + ["Bind", "excited", "Characters!"], + null, + [ + "FunctionDefinition", + "kind", + "You did it @Evaluate! This was your vision." + ], + [ + "Evaluate", + "kind", + "I… I did do it. But we also did it together." + ], + null, + [ + "Program", + "curious", + "Did we just put on our own performance?" + ], + ["Reaction", "eager", "I think we did…"], + [ + "FunctionDefinition", + "serious", + "We did… but we couldn't have done it without our new director friend. They broke our silence, they reminded us why we're expressions, together." + ], + null, + ["use", "fit", "Symbol", "?"], + [ + "FunctionDefinition", + "excited", + "So, sparkly new director, what shall we say?" + ] + ] + } + ] + } + ] +} diff --git a/static/locales/zh-CN/zh-CN.json b/static/locales/zh-CN/zh-CN.json index 06c668db2..f0697c59d 100644 --- a/static/locales/zh-CN/zh-CN.json +++ b/static/locales/zh-CN/zh-CN.json @@ -42,8 +42,8 @@ "row": "排", "set": "组", "key": "钥匙", - "help": "$! 幫助", - "feedback": "$! 回饋" + "help": "帮助", + "feedback": "反馈" }, "token": { "EvalOpen": "评估开放", @@ -77,6 +77,7 @@ "Branch": "分支", "None": "空的", "Type": "类型", + "Literal": "字面量", "TypeOperator": "类型运算符", "TypeOpen": "类型打开", "TypeClose": "类型关闭", @@ -113,21 +114,21 @@ "Name": "名字", "Unknown": "不明", "Locale": "语言环境", - "End": "结束", - "Literal": "文字" + "End": "结束" }, "node": { "Dimension": { "name": "尺寸", "description": "尺寸", - "emotion": "$?", + + "emotion": "serious", "doc": [ "我是一个/计量单位/!", "我可以是任何标准化单位,例如 \\1米\\、\\10秒\\、\\100克\\ 或任何其他科学单位。我也很高兴能成为任何想要组成的单位,比如\\17苹果\\。", "我可以与 \\/\\ 组合起来制作比率单位,如 \\17苹果/日\\ ,并与 \\^\\ 组合制作指数单位,如 \\9.8米/秒^2\\", - "我必须始终追随@数字。 如果不这样做,我可能会被误认为@参考,这会很尴尬!", + "我必须始终追随@Number。 如果不这样做,我可能会被误认为@Reference", "我也很擅长发现单位之间的不一致之处。 例如,\\1猫 + 1狗\\没有任何意义!", - "如果您想在不同的单位值之间进行转换,请与@转变交谈。" + "如果您想在不同的单位值之间进行转换,请与@Convert。" ] }, "Doc": { @@ -519,21 +520,21 @@ "ConversionDefinition": { "name": "转换定义", "description": "$1 → $2", - "emotion": "$?", + "emotion": "excited", "doc": [ - "哥们儿,我定义了从一种类型到另一种类型的转换!我在 @方块 中执行,就像这样:", + "哥们儿,我定义了从一种类型到另一种类型的转换!我在 @Block 中执行,就像这样:", "\\→ #猫咪 #猫 . ÷ 2\n6猫咪→#猫\\", "看我是如何将猫咪变成猫的?酷毙了!", "你可能想知道那个 \\.\\ 是干嘛的。那代表了正在转换的值。我用它是因为这个值不然会没有名字。" ], "start": "太棒了,一个新的转换!", "conflict": { - "MisplacedConversion": "哇,我不能在这里,只能在 @方块 中。" + "MisplacedConversion": "哇,我不能在这里,只能在 @Block 中。" } }, "Convert": { "name": "转换", - "emotion": "$?", + "emotion": "cheerful", "doc": [ "嘿,我可以将一个类型的值转换成另一个类型。看看这个例子:", "\\1 → \"\"\\", @@ -541,7 +542,7 @@ "\\\"你好\" → []\\", "你甚至可以将它们串联起来:", "\\\"你好\" → [] → {}\\", - "值具有一组预定义的 @转换定义,但如果你为一个新类型的值创建了 @结构定义,你可以使用 @转换定义 定义自己的转换规则。" + "值具有一组预定义的 @ConversionDefinition,但如果你为一个新类型的值创建了 @StructureDefinition,你可以使用 @ConversionDefinition 定义自己的转换规则。" ], "start": "从 $1 获取那个值!", "finish": "太棒了,我做到了 $1", @@ -557,7 +558,7 @@ }, "Delete": { "name": "删除", - "emotion": "$?", + "emotion": "angry", "doc": [ "有时候你有一个表格,它里面有太多东西了!", "比如说你在一个游戏中有一些玩家,其中一个离开了,你只想说“走开吧,玩家,离开我的桌子!”", @@ -569,10 +570,10 @@ }, "DocumentedExpression": { "name": "解释表达式", - "emotion": "$?", + "emotion": "eager", "doc": [ - "我是任何表达式,但附带了 @文档!", - "要创建我,只需在表达式前面加上 @文档,然后你就会得到我:", + "我是任何表达式,但附带了 @Doc!", + "要创建我,只需在表达式前面加上 @Doc,然后你就会得到我:", "\\双加: 1\n(2 · 双加) + \n``让它再大一点点``\n1\\", "我在对程序的某部分进行评论时很有用。" ], @@ -581,17 +582,17 @@ "Evaluate": { "name": "评估", "description": "评估 $1[$1|匿名]", - "emotion": "$?", + "emotion": "shy", "doc": [ - "嗨。我会评估我心爱的 @函数定义。像这样:", + "嗨。我会评估我心爱的 @FunctionDefinition", "\\ƒ 问候(消息•'')\n问候('小猫')\\", - "函数可以来自任何地方。例如,@文字 有函数。就像这样:", + "函数可以来自任何地方。例如,@Text 有函数。就像这样:", "\\'小猫'.长度()\\", - "如果一个函数只有一个符号名称,你可以将我写成 @二进制评估。", + "如果一个函数只有一个符号名称,你可以将我写成 @BinaryEvaluate", "\\'小猫' ⊆ 'itty'\\", "这与下面的语句做的是一样的事情:", "\\'小猫'.⊆('itty')\\", - "当然,没有 @函数定义 我什么也做不了。我只是为它们提供输入,然后按照它们的步骤执行。" + "当然,没有 @FunctionDefinition 我什么也做不了。我只是为它们提供输入,然后按照它们的步骤执行。" ], "start": "首先让我们评估输入", "evaluate": "现在让我们评估函数", @@ -612,7 +613,7 @@ "primary": "我缺少 $1,你能添加吗?", "secondary": "这个输入是必需的,但 $2 没有提供它" }, - "NotInstantiable": "我不能创建这个 @结构定义,它有未实现的函数。", + "NotInstantiable": "我不能创建这个 @StructureDefinition,它有未实现的函数。", "UnexpectedInput": { "primary": "我没预料到会得到这个输入 $1", "secondary": "哦,我这里不应该出现吗?" @@ -626,22 +627,22 @@ "exception": { "FunctionException": { "description": "未知函数", - "explanation": "哦不,$1 在 $2[$2|这个 @方块] 中不是一个函数!" + "explanation": "哦不,$1 在 $2[$2|这个 @Block] 中不是一个函数!" } } }, "ExpressionPlaceholder": { "name": "表达式占位符", "description": "$1[$1|占位符]", - "emotion": "$?", + "emotion": "scared", "doc": [ "我是一个 *表达式*,但不是一个真正的表达式... 我只是替代品。", "如果你还不知道要写什么,我很有用。就像这样:", "\\1 + _\\", "我们要加什么?我不知道。你告诉我。", - "或者如果有人在用 @评估 评估一个函数时,我可能会代替该函数", + "或者如果有人在用 @Evaluate 评估一个函数时,我可能会代替该函数", "\\_(1 2 3)\\", - "我不喜欢待在 @舞台 上!" + "我不喜欢待在 @Stage 上!" ], "start": "哎呀,我不知道该怎么办!", "placeholder": "表达式", @@ -658,22 +659,22 @@ "FunctionDefinition": { "name": "函数", "description": "函数 $1", - "emotion": "$?", + "emotion": "kind", "doc": [ "嗨又见面了!我接受一些输入,然后使用它们来评估一个表达式,产生一个输出。", "这里有一个简单的例子:", "\\ƒ 重复(消息•'') 消息 · 5\n重复('你好')\\", - "该函数接受一个输入,\\消息\\,并使用 @文字/重复 函数将消息重复五次。", + "该函数接受一个输入,\\消息\\,并使用 @Text/repeat 函数将消息重复五次。", "如果你想一遍又一遍地评估某些东西,但使用不同的输入,我非常有用!", - "我还有许多其他小技巧。例如,我不一定要有一个名字。在这里,我直接转到 @评估 作为一个值。", + "我还有许多其他小技巧。例如,我不一定要有一个名字。在这里,我直接转到 @Evaluate 作为一个值。", "\\(ƒ(消息•'') 消息 · 5)('你好')\\", "或者,这是一个接受任意数量输入的函数,在输入名称后加上 \\…\\ 字符。", "\\ƒ 是的(消息…•'') 消息.排除('不')\n是的('是' '是' '不' '是' '不')\\", - "看看它是如何取出所有的 '不' 并将它们去掉的?这是因为消息是一个 @列表,所以我们可以使用 @列表/排除All。", - "有时你可能想要明确我产生的值是什么类型的。为此,在输入列表之后添加一个 @是 即可:", + "看看它是如何取出所有的 '不' 并将它们去掉的?这是因为消息是一个 @List,所以我们可以使用 @List/sansAll.", + "有时你可能想要明确我产生的值是什么类型的。为此,在输入列表之后添加一个 @Is 即可:", "\\ƒ 添加(x•# y•#)•'' x + y\\", - "你可能会注意到这个例子有一个问题:它说它评估为 @文字,但它接受两个 @数字。我可以告诉你什么时候事情不一致!", - "当然,没有 @评估,我根本不实用;他们让我活了过来。" + "你可能会注意到这个例子有一个问题:它说它评估为 @Text,但它接受两个 @Number。我可以告诉你什么时候事情不一致!", + "当然,没有 @Evaluate,我根本不实用;他们让我活了过来。" ], "start": "让我们创建这个函数!", "conflict": { @@ -682,8 +683,8 @@ }, "Iteration": { "name": "高阶函数", - "emotion": "$?", - "doc": "我是一种非常特殊的 @函数定义,用于操作物品列表。除了我使得像 @列表/翻译 这样的函数成为可能之外,你不需要了解太多关于我。", + "emotion": "kind", + "doc": "我是一种非常特殊的 @FunctionDefinition,用于操作物品列表。除了我使得像 @List/translate 这样的函数成为可能之外,你不需要了解太多关于我。", "start": "评估给定的函数", "initialize": "准备逐个遍历项目", "next": "移动到下一个项目", @@ -692,22 +693,22 @@ }, "Initial": { "name": "开始", - "emotion": "$?", + "emotion": "curious", "doc": [ - "我告诉你 @节目 的当前评估是否是第一个,评估为一个 @布尔值。例如:", + "我告诉你 @Program 的当前评估是否是第一个,评估为一个 @BooleanLiteral", "\\◆ ? 时间() '你好'\\", - "你没有看到它,但第一次评估是一个时间,但随后所有未来的时间标记,我都是 \\⊥\\,所以 @有条件的 使得 \\⊤\\。", + "你没有看到它,但第一次评估是一个时间,但随后所有未来的时间标记,我都是 \\⊥\\,所以 @Conditional 使得 \\⊤\\。", "如果你正在处理一个流,并且你只想在第一次执行某些操作时使用我,或者在第一次时根本不使用我,那我会非常有用!" ] }, "Insert": { "name": "插入", - "emotion": "$?", + "emotion": "kind", "doc": [ - "你知道当你有一个 @桌子 时,总觉得缺了点什么吗?我可以帮你添加!", + "你知道当你有一个 @Table 时,总觉得缺了点什么吗?我可以帮你添加!", "想象一下你有一个游戏中的玩家表,你想添加一个新玩家:", "\\玩家: ⎡姓名•'' 队伍•'' 分数•#⎦\n⎡'珍' '红' 1⎦\n⎡'琼' '蓝' 0⎦\n⎡'杰夫' '红' 3⎦\n⎡'珍妮特' '蓝' 2⎦\n玩家 ⎡+ '贾森' '红' 0⎦\\", - "请记住,就像 Verse 中的所有事物一样,我不会改变表格,我会修订它。所以你需要想清楚你想把你修改后的表格放在哪里。最有可能的是你会想在对某个输入的 @反应 中修改一个表格,并将其存储在 @绑定 中。" + "请记住,就像 Verse 中的所有事物一样,我不会改变表格,我会修订它。所以你需要想清楚你想把你修改后的表格放在哪里。最有可能的是你会想在对某个输入的 @Reaction 中修改一个表格,并将其存储在 @Bind 中。" ], "start": "让我们找到要更新的表格", "finish": "我创建了一张带有修订行的新表格!" @@ -715,15 +716,15 @@ "Is": { "name": "是", "description": "是", - "emotion": "$?", + "emotion": "curious", "doc": [ "你知道吗?有很多种意味着很多不同含义的值。我可以帮忙确定它们是什么。", - "例如,假设你有一个神秘值。我可以告诉你它是否是一个 @数字,给你一个 @布尔值:", + "例如,假设你有一个神秘值。我可以告诉你它是否是一个 @Number,给你一个 @Boolean:", "\\神秘: '秘密!'\n神秘•#\\", - "这不是一个数字,所以我得到了 \\⊥\\。但如果我们检查它是否是 @文字类型?", + "这不是一个数字,所以我得到了 \\⊥\\。但如果我们检查它是否是 @TextType?", "\\神秘: '秘密!'\n神秘•''\\", "我们得到了 \\⊤\\!", - "当你需要知道某个 @名字 是否具有特定类型的值时,我非常有用。" + "当你需要知道某个 @Name 是否具有特定类型的值时,我非常有用。" ], "start": "首先让我们获取 $1 的值", "finish": "$1[值是 $2|值不是 $2]", @@ -740,7 +741,7 @@ "IsLocale": { "name": "区域语言检查", "description": "区域语言检查", - "emotion": "$?", + "emotion": "kind", "doc": [ "我将帮你检查观众是否选择了特定的语言或地区:", "\\🌍/en\\", @@ -751,9 +752,9 @@ }, "ListAccess": { "name": "列表访问", - "emotion": "$?", + "emotion": "cheerful", "doc": [ - "我与 @列表 密切合作,帮助它们在特定位置获取值。所以,比如,如果你有一个列表,想要获取它的第二个项目,你会写成:", + "我与 @List 密切合作,帮助它们在特定位置获取值。所以,比如,如果你有一个列表,想要获取它的第二个项目,你会写成:", "\\列表: ['鸟' '鸭' '鱼' '蛇']\n列表[2]\\" ], "start": "首先让我们获取列表 $1", @@ -762,8 +763,8 @@ "ListLiteral": { "name": "特定列表", "description": "$1 项目列表", - "emotion": "$?", - "doc": "我是一个具体的值 @列表!查看 @列表 以了解更多关于如何使用我的信息。", + "emotion": "eager", + "doc": "我是一个具体的值 @List!查看 @List 以了解更多关于如何使用我的信息。", "start": "让我们先评估这些项目", "finish": "我创建了一个我! $1", "item": "项目" @@ -779,8 +780,8 @@ "MapLiteral": { "name": "映射", "description": "$1 配对映射", - "emotion": "$?", - "doc": "我是一个具体的键值对 @地图。查看 @地图 以了解我如何提供帮助的更多信息。", + "emotion": "kind", + "doc": "我是一个具体的键值对 @Map。查看 @Map 以了解我如何提供帮助的更多信息。", "start": "让我们先评估键和值", "finish": "我把每个连接在一起了,$1", "conflict": { @@ -793,8 +794,8 @@ "NumberLiteral": { "name": "具体数字", "description": "$1 $2[$2|]", - "emotion": "$?", - "doc": "我是一个具体的 @数字。你可以用任何语言的任何数字来书写我。查看 @数字 了解我能做的一切。", + "emotion": "excited", + "doc": "我是一个具体的 @Number。你可以用任何语言的任何数字来书写我。查看 @Number 了解我能做的一切。", "start": "$1!", "conflict": { "NotANumber": "我以为我认识所有的数字,但我不认识这个" @@ -802,25 +803,25 @@ }, "InternalExpression": { "name": "内部表达式", - "emotion": "$?", + "emotion": "neutral", "doc": "你是怎么找到我的?我是只有原创作者才使用的表达式。要了解更多关于我的信息,你需要和他们交谈。", "start": "秘密表达式" }, "NoneLiteral": { "name": "非字面意义", - "emotion": "$?", - "doc": "/@函数定义 在此。这只是 @空的。它们是独一无二的!查看 @空的 以了解更多关于它们的信息。", + "emotion": "neutral", + "doc": "/@FunctionDefinition 在此。这只是 @None。它们是独一无二的!查看 @None 以了解更多关于它们的信息。", "start": "… ø" }, "Previous": { "name": "之前", - "emotion": "$?", + "emotion": "serious", "doc": [ "你有没有想过记住过去?", "我是 诗 的官方记录员。给我一个流和一个数字,我会往回看,告诉你那个流在历史上的值是什么。", - "例如,这是五个滴答前的 @时间 是什么时候:", + "例如,这是五个滴答前的 @Time 是什么时候:", "\\← 5 时间(1000ms)\\", - "看到了吗?它在 5 秒钟内都是 @空的,然后突然出现了一个先前的时间?", + "看到了吗?它在 5 秒钟内都是 @None,然后突然出现了一个先前的时间?", "如果你想要最后几个值,给我两个箭头,我会将数字解释为一个计数:", "\\←← 5 时间(1000ms)\\", "看到了吗?这是五个先前的时间,而不是只有一个时间?", @@ -831,12 +832,12 @@ }, "Program": { "name": "节目", - "emotion": "严肃", + "emotion": "serious", "doc": [ "我是表演的开始和结束,包含了所有编排表演的其他角色。", - "你知道 @方块 如何评估表达式列表,并将其列表中的最后一个评估结果返回?", - "我也一样,但与其将我的值提供给我所在的表达式,我会将该值放在 @舞台 上。", - "这个值可以是任何东西:@数字、@文字 或 @布尔值,@列表、@集合、@地图,甚至更复杂的东西,如 @短语、@组 或 @舞台。", + "你知道 @Block 如何评估表达式列表,并将其列表中的最后一个评估结果返回?", + "我也一样,但与其将我的值提供给我所在的表达式,我会将该值放在 @Stage 上。", + "这个值可以是任何东西:@Number、@Text 或 @Boolean,@List、@Set、@Map,甚至更复杂的东西,如 @Phrase、@Group 或 @Stage。", "如果你没有给我一个在舞台上展示的值,我会要求你提供一个。", "如果在表演过程中出现问题,我会显示出这个问题。", "如果你的表演依赖于一个*流*,我会在该流改变时重新评估。" @@ -853,7 +854,7 @@ }, "EvaluationLimitException": { "description": "评估限制", - "explanation": "@评估 和我对于评估感到疲惫,尤其是 $1。\n\n是不是可能 $1 在永远地评估自己,永远不会停止?" + "explanation": "@Evaluate 和我对于评估感到疲惫,尤其是 $1。\n\n是不是可能 $1 在永远地评估自己,永远不会停止?" }, "StepLimitException": { "description": "步骤限制", @@ -868,7 +869,7 @@ "PropertyBind": { "name": "精炼", "description": "精炼$1[$1|缺少名称]", - "emotion": "善良", + "emotion": "kind", "doc": [ "有时,当你创建一个@StructureDefinition时,你想要改变它的最小的东西,而不必用所有相同的值创建一个新的。", "例如,如果你正在保存猫的记录,但然后想创建一个具有不同爱好的猫的副本,该怎么办?我可以帮你改。", @@ -881,7 +882,7 @@ "PropertyReference": { "name": "性质", "description": "属性$1[$1|缺少名称]", - "emotion": "善良", + "emotion": "kind", "doc": [ "当您创建一个@StructureDefinition时,您如何获得它的一个输入?我如何", "比如,如果你有一个关于城市的结构,你可以像这样得到它的值:", @@ -893,7 +894,7 @@ }, "Reaction": { "name": "反应", - "emotion": "兴奋", + "emotion": "excited", "doc": [ "流是如此的棒!我可以根据它们的变化来制作新的,这太酷了!", "比如,如果你想让@Time打勾,但想显示单词而不是数字,你可以这样做:", @@ -913,16 +914,16 @@ "Reference": { "name": "参考", "description": "$1", - "emotion": "害羞", + "emotion": "shy", "doc": [ - "你知道@Bind怎么给东西@Name吗?我就是你所说的他们。我看看@Bind是否有那个名字,如果有,给你它的值。是这样的:", + "你知道@Bind怎么给东西 @Name 吗?我就是你所说的他们。我看看@Bind是否有那个名字,如果有,给你它的值。是这样的:", "\\鹦鹉:\nparrot \\“波利”", "如果我找不到名字,我就不知道该怎么办了。", "\\鹦鹉:\nperry\\“波利”" ], "start": "1$有什么价值?", "conflict": { - "UnknownName": "我不知道有谁叫$1在$2里$2这个@Block你能给我一个名字吗?]", + "UnknownName": "我不知道有谁叫$1在$2里$2这个 @Block 你能给我一个名字吗?]", "ReferenceCycle": "1$的价值取决于它本身,所以我怎么知道应该给它什么价值呢?", "UnexpectedTypeVariable": "我不知道该怎么处理这些输入" }, @@ -935,7 +936,7 @@ }, "Select": { "name": "选择", - "emotion": "兴奋的", + "emotion": "excited", "doc": [ "有时你有一张桌子,你只想占有它的一部分。我可以帮你拿来!", "比如,如果你在游戏中有一张玩家表,你想找出得分在10分以上的人,看看谁赢了:", @@ -951,14 +952,14 @@ "SetLiteral": { "name": "具体组", "description": "$1,物体", - "emotion": "急切的", + "emotion": "eager", "doc": "我是特定值的特定集合。查看@Set了解更多关于如何与我合作的信息。", "start": "让我们先估计数值吧", "finish": "我做了一个组$1" }, "SetOrMapAccess": { "name": "组/映射组的访问", - "emotion": "善良", + "emotion": "kind", "doc": [ "我可以看到@Set或@Map是否有值或键。", "这并不难。是这样的:", @@ -977,23 +978,23 @@ }, "Source": { "name": "资源", - "emotion": "好奇", + "emotion": "curious", "doc": [ - "哦,你知道@Program吗?我帮你取名字。把我想象成@Program周围的窗口,以及你给他们起的名字。", - "你也可以创建其他@Source @UI/addSource,使用其他@Program,并从其他@Program中@Borrow东西以供其他程序使用。", + "哦,你知道 @Program 吗?我帮你取名字。把我想象成 @Program 周围的窗口,以及你给他们起的名字。", + "你也可以创建其他 @Source @UI/addSource ,使用其他 @Program ,并从其他@Program中@Borrow东西以供其他程序使用。", "这是将大型表现组织到单独文档中的好方法。" ] }, "StreamDefinition": { "name": "流", - "emotion": "好奇", + "emotion": "curious", "doc": "我/我想/我应该创造新的溪流。但我真的不知道该怎么做。现在,我想就用现有的流吧?", "start": "创建这种新的流" }, "StructureDefinition": { "name": "结构", "description": "结构 $1", - "emotion": "善良", + "emotion": "kind", "doc": [ "你好,你好吗?我吗?我很好。我喜欢定义存储值和功能的结构,所以只要我能整天这样做,我就很高兴。", "我这样工作!", @@ -1014,345 +1015,491 @@ } }, "TableLiteral": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?", - "start": "$?", - "finish": "$?" + "name": "表面量", + "description": "$1 行表格", + "emotion": "angry", + "doc": "我是一个具有特定行数的特定表格。请参阅 @Table 了解我如何提供帮助。", + "start": "首先评估行数", + "finish": "评估为新表格 $1" }, "TextLiteral": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?", - "start": "$?" + "name": "文本量", + "description": "文本 $1", + "emotion": "serious", + "doc": "我代表一个或多个特定的文本翻译。请参阅 @Text 以了解我可以做什么!", + "start": "让我们在当前语言环境中创建文本" }, "Translation": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?" + "name": "翻译", + "description": "翻译 $1", + "emotion": "serious", + "doc": "我代表一些文本,带有 @Language 标签。请参阅 @Text 以了解更多!" }, "FormattedLiteral": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?", - "start": "$?" + "name": "格式文本", + "description": "文本 $1", + "emotion": "serious", + "doc": "我代表许多不同的格式化文本的 @FormattedTranslation。当我进行评估时,我会根据受众选择的语言选择最佳匹配。", + "start": "让我们创建当前语言环境下的文本" }, "FormattedTranslation": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?" + "name": "格式化", + "description": "文本 $1", + "emotion": "serious", + "doc": [ + "我代表一些格式化的文本,带有 @Language 标签。", + "我可以是:", + "\\`/斜体/`\\", + "\\`*加粗*`\\", + "\\`^超粗^`\\", + "\\`_下划线_`\\", + "\\`<链接@https://wordplay.dev>`\\", + "\\`\\'代码'\\`\\", + "我与 @Phrase 结合使用,将漂亮的文本呈现在 @Stage 上。" + ] }, "This": { - "name": "$?", - "emotion": "$?", - "doc": "$?", - "start": "$?", + "name": "这个", + "emotion": "serious", + "doc": [ + "有时候,隐含地引用值比命名它更有帮助。", + "例如,假设您想创建一个新的 @ConversionDefinition,它不命名正在转换的值。您可以使用我来引用它:", + "\\→ #彩虹 #欢乐 . · 1000000欢乐\n2彩虹 → #欢乐\\", + "看看这里,代表彩虹数量的部分?", + "或者,假设您想创建一个 @Reaction,但不想为最近的值命名:", + "\\2 … ∆ 时间(1000毫秒) … . · 2\\", + "看看我,代表前一个反应值。", + "我不经常出现,但当出现时,我可以帮助值摆脱 @Bind!" + ], + "start": "评估为 $1", "conflict": { - "MisplacedThis": "$?" + "MisplacedThis": "我只允许出现在结构、转换或反应中。" } }, "UnaryEvaluate": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?", - "start": "$?", - "finish": "$?" + "name": "一元评估", + "description": "$1", + "emotion": "kind", + "doc": [ + "您知道当我仅对一个值进行 @FunctionDefinition 评估时,@FunctionDefinition 的名称只是一个单一的符号,您可以将名称放在输入值之前吗?", + "像这样:", + "\\-(1 + 1)\\", + "或者这样:", + "\\~⊥\\", + "相比 \\(1 + 1).negate()\\ 或 \\⊥.not()\\,这样写更容易阅读,不是吗?", + "您不必这样写,但总体来说可能更容易。", + "只有一个规则:名称和值之间不能有空格。否则,您可能会创建 @Reference 或 @BinaryEvaluate。" + ], + "start": "值是什么?", + "finish": "我完成了 $1" }, "UnparsableExpression": { - "name": "$?", - "emotion": "$?", - "doc": "$?", - "start": "$?", + "name": "不可解析", + "emotion": "excited", + "doc": [ + "/嗨,这里是 @FunctionDefinition。由于通常很难解释 @UnparsableExpression,我将代为翻译。", + "jkwel fjiwojvioao jjiweo jrfe", + "/并不是每个表达式在舞台上都有意义/", + "s w ieorjwei iojwi jfkdlsfdsk", + "/事实上,有各种各样的东西可以说出来,但根本没有任何意义/", + "dsk sdlk jdkfiewipapweiurb,v kdsfdsf", + "/当您这样做时,我会出现,因为我不知道您的意思/", + "毕竟您是导演,只有您知道您可能的意思!" + ], + "start": "???", "conflict": { - "UnparsableConflict": "$?", - "UnclosedDelimiter": "$?" + "UnparsableConflict": "@FunctionDefinition 在此,@UnparsableExpression 不知道这是什么类型的 $1[表达式 | 类型]。", + "UnclosedDelimiter": "我期望在 $1 之后的某个时刻会有 $2" }, "exception": { "UnparsableException": { - "description": "$?", - "explanation": "$?" + "description": "???", + "explanation": "/嗨,这里是 @FunctionDefinition!我们不知道这是什么类型的指令,所以不得不停下来!/" } } }, "Update": { - "name": "$?", - "emotion": "$?", - "doc": "$?", - "start": "$?", - "finish": "$?", + "name": "更新", + "emotion": "kind", + "doc": [ + "我帮助修订 @Table,找到与条件匹配的行,然后创建具有新值的修订行。", + "例如,如果您有一个包含角色和点数的表格,并且想要为同一团队的每个角色添加一个点数,您可以这样做:", + "\\players: ⎡name•'' team•'' points•#⎦\n⎡'jen' 'red' 1⎦\n⎡'joan' 'blue' 0⎦\n⎡'jeff' 'red' 3⎦\n⎡'janet' 'blue' 2⎦\nplayers ⎡: points: points + 1 ⎦ team = 'blue'\\", + "您可以使用 @Bind 指定要更改的列,还可以在条件中使用列名称或范围中的其他名称。" + ], + "start": "首先让我们获取表格", + "finish": "评估为具有修订行的新表格!", "conflict": { - "ExpectedColumnBind": "$?", - "IncompatibleCellType": { "primary": "$?", "secondary": "$?" } + "ExpectedColumnBind": "我需要每列的值", + "IncompatibleCellType": { + "primary": "我需要一个 $1,但得到了 $2", + "secondary": "我得到了一个 $2" + } } }, "AnyType": { - "name": "$?", - "emotion": "$?", - "doc": "$?" + "name": "任意", + "emotion": "curious", + "doc": "我代表任何可能的类型。有时我会出现,因为不知道某些东西是什么类型,所以它可以是任何类型。" }, "BooleanType": { - "name": "$?", - "emotion": "$?", - "doc": "$?" + "name": "布尔", + "emotion": "kind", + "doc": [ + "我与 @Bind 一起工作,声明名称是 @Boolean 值。就像这样:", + "\\hungry•?: 'jello'\\", + "如果要确保某物是 @Boolean,请使用我,我会检查!" + ] }, "ConversionType": { - "name": "$?", - "emotion": "$?", - "doc": "$?" + "name": "转换", + "emotion": "serious", + "doc": [ + "我与 @Bind 一起工作,指示名称是 @ConversionDefinition。您可能不需要使用我,因为没有多少人将我作为值传递,但如果您这样做,我将如下所示:", + "\\magic•?→'': → ? '' . ? 'yep' 'nope'\\" + ] }, "FormattedType": { - "name": "$?", - "emotion": "$?", - "doc": "$?" + "name": "格式化", + "emotion": "serious", + "doc": [ + "我与 @Bind 一起注明名称是 @FormattedLiteral 值。就像这样:", + "\\hungry•`…`: `I am so /fancy/!`\\", + "想要确保某物是 @FormattedLiteral 值?这就是您确保的方法。" + ] }, "ExceptionType": { - "name": "$?", - "emotion": "$?", - "doc": "$?" + "name": "异常", + "emotion": "neutral", + "doc": "我代表一个异常。没有办法告诉绑定我是一个异常,因为异常只会中止 @Program,所以无法将它们用作值。" }, "FunctionType": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?" + "name": "函数", + "description": "带有 $1 输入和 $2 输出的函数", + "emotion": "curious", + "doc": [ + "我代表 @FunctionDefinition。如果要说明 @Bind 包含的是什么类型的函数,我会非常有帮助!就像这样:", + "\\math•ƒ (# # # #) #: ƒ interesting(a•# b•# c•# d•#) a + b + c + d\\" + ] }, "ListType": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?" + "name": "列表", + "description": "$1[$1 列表|$1]", + "emotion": "cheerful", + "doc": [ + "我是 @List 的狂热爱好者。我可以告诉 @Bind 他们是什么类型的列表!就像这样,我告诉他们这是 @Number 的列表:", + "\\things•[#]: [ 1 2 3 4 5 ]\\" + ] }, "MapType": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?" + "name": "映射", + "description": "$1[$1|任意] 到 $2[$2|任意] 的映射", + "emotion": "kind", + "doc": [ + "您知道 @Map 有多棒吗?真的很棒。我总是告诉 @Bind 他们是什么类型的映射,就像这样将数字映射到列表:", + "\\stuff•{'':[]}: {}\\" + ] }, "NumberType": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?" + "name": "数值", + "description": "$1[$1 | 数值]", + "emotion": "precise", + "doc": [ + "你知道 @Bind 应该是什么吗?应该是 @Number。因为数值是最好的。", + "\\计数•#: 17\\" + ] }, "NameType": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?", + "name": "结构", + "description": "$1 类型", + "emotion": "curious", + "doc": [ + "我通过名称代表 @StructureDefinition。所以,如果你有这样一个结构,你可以创建一个 @Bind 来存储它所创建的值。", + "\\•朋友(名字•'')\n最好朋友•朋友: 朋友('乔纳')\\" + ], "conflict": { - "UnknownTypeName": "$?" + "UnknownTypeName": "类型名称只能指代结构或类型变量,但这里指代了一个 $1" } }, "NeverType": { - "name": "$?", - "emotion": "$?", - "doc": "$?" + "name": "不可能", + "emotion": "curious", + "doc": "我代表一种不可能的类型。就像当你询问 @Is 是否是 @Number,但它永远不可能是一个数值时一样。" }, "NoneType": { - "name": "$?", - "emotion": "$?", - "doc": "$?" + "name": "无", + "emotion": "neutral", + "doc": [ + "@None 是最好的不存在之一,而我是它们的忠实代表。", + "\\空间•ø: ø\\" + ] }, "SetType": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?" + "name": "集合", + "description": "$1[$1 集合|集合]", + "emotion": "kind", + "doc": [ + "@Set 是最好的,真的。我一直告诉 @Bind,让事物成为某种东西的集合!", + "\\独特•{''}: {'某物' '任何物' '某人'}\\" + ] }, "StreamDefinitionType": { - "name": "$?", - "emotion": "$?", - "doc": "$?" + "name": "流定义", + "emotion": "angry", + "doc": "我代表你定义的流,这是不可能的,那么为什么你还在阅读这个?" }, "StreamType": { - "name": "$?", - "emotion": "$?", - "doc": "$?" + "name": "流", + "emotion": "curious", + "doc": [ + "我庆祝流的美丽和意义... 通过告诉 @Bind 来存储它们:", + "\\时间•…#毫秒: 时间()\\" + ] }, "StructureType": { - "name": "$?", + "name": "结构", "description": "$1", - "emotion": "$?", - "doc": "$?" + "emotion": "kind", + "doc": "我是一个内部类型,代表默认值类型的类型。" }, "UnknownType": { - "name": "$?", - "connector": "$?", - "emotion": "$?", - "doc": "$?" + "name": "未知", + "connector": ",因为", + "emotion": "curious", + "doc": "嗯...我不知道我代表什么,但我真的很好奇。你知道吗?似乎我们应该知道。如果我们无法弄清楚,你可能需要告诉我们。" }, "TableType": { - "name": "$?", - "emotion": "$?", - "doc": "$?", + "name": "表", + "emotion": "angry", + "doc": "我代表一个表。", "conflict": { - "ExpectedColumnType": "$?" + "ExpectedColumnType": "我需要一个列类型" } }, "TextType": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?" + "name": "文本", + "description": "$1[$1|文本]", + "emotion": "happy", + "doc": [ + "我精彩地代表最精彩的值,@Text。", + "\\故事•'': '从前有一个故事...'\\" + ] }, "TypePlaceholder": { - "name": "$?", - "emotion": "$?", - "doc": "$?" + "name": "占位", + "emotion": "eager", + "doc": "我希望有一天能代表一种类型,有点像我的好朋友 @ExpressionPlaceholder 代表一个表达式!你会帮助我决定是什么类型吗?" }, "UnionType": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?" + "name": "选项", + "description": "$1 | $2", + "emotion": "curious", + "doc": [ + "我应该代表谁,A 还是 B 还是其他什么?我永远无法决定!", + "\\犹豫•''|#|{ø}: \"我不知道!\"\\" + ] }, "Unit": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?" + "name": "单位", + "description": "$1", + "emotion": "precise", + "doc": [ + "我代表 @Number 可能具有的任何单位,包括无单位,以及你可以想象的最复杂单位。比如重力:", + "\\重力•米/秒^2: 9.8米/秒^2\\", + "我出现在 @Bind 之后,也出现在 @Number 之后。我帮助确保数字具有相同的类型,如果它们不同,我肯定会告诉你,以防是个错误!" + ] }, "UnparsableType": { - "name": "$?", - "emotion": "$?", - "doc": "$?" + "name": "无法解析", + "emotion": "curious", + "doc": "我代表未知表达式的类型。当你尝试将该表达式用于某事时,我会出现。" }, "VariableType": { - "name": "$?", - "emotion": "$?", - "doc": "$?" + "name": "变量类型", + "emotion": "curious", + "doc": "你了解 @TypeVariable,以及它们代表某种未知类型的值吗?我在值之间的所有协商中代表它们。" }, "CycleType": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?" + "name": "循环", + "description": "依赖于自身", + "emotion": "curious", + "doc": "有时值依赖于自身,所以我们不知道它们是什么类型的值。我代表这种情况。" }, "UnknownVariableType": { - "name": "$?", - "emotion": "$?", - "doc": "$?" + "name": "未知变量", + "emotion": "curious", + "doc": "有时我们试图猜测某种值的类型;当我们不知道时,我会出现。" }, "NotAType": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?" + "name": "意外", + "description": "不是 $1", + "emotion": "curious", + "doc": "有时我们知道某种值应该是什么类型,就像 @ListAccess 需要 @Number 一样。如果我们没有得到它,我代表某个类型与我们预期的不同。" }, "NoExpressionType": { - "name": "$?", - "emotion": "$?", - "doc": "$?" + "name": "无表达式", + "emotion": "angry", + "doc": "你知道 @Block 至少需要一个表达式吗?当你不提供一个表达式时,我就是你得到的。所以,请提供一个!" }, "NotEnclosedType": { - "name": "$?", - "emotion": "$?", - "doc": "$?" + "name": "不在结构、转换或反应中", + "emotion": "curious", + "doc": "@This,尽管它很好,但只适用于特定的地方。当它们迷路时,我会出现,所以没有人知道它们代表什么值。" }, "NotImplementedType": { - "name": "$?", - "emotion": "$?", - "doc": "$?" + "name": "未实现", + "emotion": "curious", + "doc": "当你使用 @ExpressionPlaceholder,但没有说明它们的类型时,我就是你得到的类型。接受吧!" }, "UnknownNameType": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?" + "name": "未知名称", + "description": "$1[$1 未定义|未提供名称]", + "emotion": "curious", + "doc": "你知道有时候 @Reference 和 @PropertyReference 不知道你在谈论什么名称吗?当发生这种情况时,我会出现,代表我们不知道你在谈论谁。" }, "NonFunctionType": { - "name": "$?", - "description": "$?", - "emotion": "$?", - "doc": "$?" + "name": "非函数", + "description": "非函数", + "emotion": "confused", + "doc": "有些人期望函数;当我们没有得到函数时,我就会出现。" } }, "basis": { "Boolean": { - "doc": "$?", - "name": "$?", + "doc": [ + "我们是 \\⊤\\ 和 \\⊥\\。 \\⊤\\ 为真。 \\⊥\\ 为假。 \\⊤\\ 不是 \\⊥\\; \\⊥\\ 也不是 \\⊤\\。 就是这样。", + "要如何创建我们?只需要 \\⊤\\ 和 \\⊥\\,没有多余的东西。", + "有些人使用键盘(按 /ctrl+9/ 输入 \\⊤\\,按 /ctrl+0/ 输入 \\⊥\\)。有些人使用编辑器底部的字符搜索功能。或者,你可以从这里拖动我们。", + "请查看我们下面的 @FunctionDefinition。它们非常逻辑。" + ], + "name": ["⊤⊥", "布尔"], "function": { "and": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "我仅在两个值都是 \\⊤\\ 时才评估为 \\⊤\\。对于确定许多事情是否都为真非常有帮助。只有四种可能的结果", + "\\⊤ & ⊤\\", + "\\⊤ & ⊥\\", + "\\⊥ & ⊤\\", + "\\⊥ & ⊥\\" + ], + "names": ["&", "和"], + "inputs": [ + { + "doc": "用于检查的另一个 @Boolean。如果第一个是 \\⊥\\,那么这个值是什么不重要,该函数将评估为 \\⊥\\。", + "names": "值" + } + ] }, "or": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "我仅在两个值中有一个是 \\⊤\\ 时才评估为 \\⊤\\。对于确定许多事情是否有一个为真非常有帮助。只有四种可能的结果", + "\\⊤ | ⊤\\", + "\\⊤ | ⊥\\", + "\\⊥ | ⊤\\", + "\\⊥ | ⊥\\" + ], + "names": ["|", "或"], + "inputs": [ + { + "doc": "用于检查的另一个 @Boolean。如果第一个是 \\⊥\\,该函数将仅在此值为 \\⊤\\ 时评估为 \\⊤\\。", + "names": "值" + } + ] + }, + "not": { + "doc": "我得到与自己相反的结果:如果是 \\⊤\\,则得到 \\⊥\\;如果是 \\⊥\\,则得到 \\⊤\\。", + "names": ["~", "非"], + "inputs": [] }, - "not": { "doc": "$?", "names": "$?", "inputs": [] }, "equals": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": "如果两者都是 \\⊤\\ 或两者都是 \\⊥\\,则为 \\⊤\\。", + "names": ["=", "等于"], + "inputs": [ + { "doc": "要检查的另一个值。", "names": "值" } + ] }, "notequal": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": "如果两者相反,则为 \\⊤\\。", + "names": ["≠", "不等于"], + "inputs": [ + { "doc": "要检查的另一个值。", "names": "值" } + ] } }, - "conversion": { "text": "$?" } + "conversion": { + "text": "将 @布尔 转换为等效的 @文本 值,即 \\'⊤'\\ 和 \\'⊥'\\" + } }, "None": { - "doc": "$?", - "name": "$?", + "doc": [ + "/嗨,@FunctionDefinition 在这里。@None 不太喜欢说话,所以我来解释一下。/", + "我是 @None。使用 \\ø\\ 调用我。当你想要表示不存在的东西时,我很有用。" + ], + "name": ["ø", "无"], "function": { "equals": { - "doc": "$?", - "names": ["=", "equals"], - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": "另一个值也是不存在吗?最好是,否则,\\⊥\\。", + "names": ["=", "等于"], + "inputs": [{ "doc": "另一个值。", "names": "值" }] }, "notequals": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": "另一个值是否 /不/ 不存在?", + "names": ["≠", "不等于"], + "inputs": [{ "doc": "另一个值。", "names": "值" }] } }, - "conversion": { "text": "$?" } + "conversion": { + "text": "想要将 \\ø\\ 转换为 \\'ø'\\ 吗?这是你的机会。" + } }, "Text": { - "doc": "$?", - "name": "$?", + "doc": [ + "我可以是你喜欢的任何文字,来自任何语言,并使用这些开头和结尾符号之一:\\\"\"\\、\\“”\\、\\„“\\、\\''\\、\\‘’\\、\\‹›\\、\\«»\\、\\「」\\或 \\『』\\。", + "举个例子,考虑这些美丽的短语", + "\\“生活有两种方式。一种是好像没有什么是奇迹的。另一种是好像一切都是奇迹的。”\\", + "\\『一日三秋』\\", + "只需记住,如果你打开了我,就要关闭我,并使用相匹配的符号。否则,我就不知道你已经用完了你的话。", + "\\'hello'/en'hola'/es-MX\\", + "你还可以为我加上语言标记,甚至提供多个翻译。如果当前选择了匹配的语言,我将评估为相应的语言。", + "如果你想用一些其他值来制作我,你可以使用一个符号", + "例如,考虑这个:", + "\\\"这里有一些和 \\1 + 2\\, \\2 + 3\\, \\3 + 4\\\"\\", + "看看我是如何优雅地评估这些和,并将它们放在 @Text 中的?", + "另外,@FunctionDefinition 为我准备了许多精彩的函数,可以用各种文字做各种事情!" + ], + "name": ["''", "文本"], "function": { - "length": { "doc": "$?", "names": "$?", "inputs": [] }, + "length": { + "doc": [ + "我评估为文本中可读字符的数量;一个字母是一个字符,一个表情符号也是一个字符,依此类推。例如:", + "\\'hello'.length()\\", + "\\'🐈📚'.length()\\" + ], + "names": ["📏", "长度"], + "inputs": [] + }, "equals": { - "doc": "$?", - "names": ["=", "equals"], - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": "如果我与给定的 @Text 具有相同的字符序列,则为 \\⊤\\。", + "names": ["=", "等于"], + "inputs": [{ "doc": "要比较的 @Text。", "names": "值" }] }, "notequals": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] - }, - "repeat": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] - }, - "segment": { - "doc": "$?", - "names": ["segmentar"], - "inputs": [{ "doc": "$?", "names": "$?" }] - }, - "combine": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": "如果我与给定的 @Text 的字符序列不同,则为 \\⊤\\。", + "names": "≠", + "inputs": [{ "doc": "要比较的 @Text", "names": "值" }] }, "has": { - "doc": "$?", - "names": ["tiene"], - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "如果给定的 @Text 出现在我中,为 \\⊤\\。", + "\\'你找到你要找的东西了吗?'.has('you')\\" + ], + "names": ["⊆", "包含"], + "inputs": [ + { + "doc": "要在我中搜索的 @Text。", + "names": "文本" + } + ] }, "starts": { "doc": [ @@ -1374,16 +1521,59 @@ "\\'我是一个问句吗?'。以('?')结尾\\", "\\'我不是一个问句。'。 以('?')结尾\\" ], - "names": ["ends"], + "names": ["结束"], "inputs": [ { "doc": "这样的 @Text 为我检查了文本的结尾。", "names": "文本" } ] + }, + "repeat": { + "doc": [ + "我创建一个新的 @Text,就是我,重复了 \\计数\\ 次:", + "\\'嗨 ' · 5\\", + "如果你给我一个分数 @Number,我会忽略小数部分:", + "\\'嗨 ' · 5.5\\", + "如果你给我一个负数 @Number 或零,我会返回一个空的 @Text。", + "\\'嗨 ' · -5\\" + ], + "names": ["·", "🔁", "重复"], + "inputs": [ + { + "doc": "在新文本中重复自己的次数。", + "names": "计数" + } + ] + }, + "segment": { + "doc": [ + "我将自己分成一个 @Text 的 @List,使用给定的 @Text 作为分隔符,并删除分隔符。例如:", + "\\'苹果,橙子,葡萄' ÷ ', '\\", + "如果分隔符是一个空的 @Text,我会将自己分成字符:", + "\\'🖌️🏠🥸' ÷ ''\\" + ], + "names": ["÷", "分段"], + "inputs": [ + { + "doc": "要用作分隔符的 @Text。", + "names": "分隔符" + } + ] + }, + "combine": { + "doc": [ + "有时将两个 @Text 合并在一起很有帮助。给我另一个 @Text,我会创建一个新的文本,将我们连接在一起:", + "\\'你好 ' + '诗'\\" + ], + "names": ["+", "组合"], + "inputs": [{ "doc": "要附加的 @Text。", "names": "文本" }] } }, - "conversion": { "list": "$?", "number": "$?" } + "conversion": { + "list": "将文本分割成单个字符的列表。", + "number": "将文本转换成 @Number,如果不是数值,则为非数值值。" + } }, "Number": { "doc": [ @@ -1399,21 +1589,21 @@ "同样地,无数个数字和单位的排列组合……", "我可以是整数、实数、负数、正数、分数、小数,甚至不是一个数字。", "你可以将我用不同的数字系统表达, 像阿拉伯数字 \\123\\, 罗马数字 \\ⅩⅩⅩⅠⅩ\\, 日本数字 \\二十\\, 甚至将它们混合起来:", - "\\1 + Ⅰ + 一\\", - "你也可以将我写成二进制,比如二进制的16会像这样:", + "\\1 + I + 一\\", + "你也可以将我写成二进制,比如二进制的16会像这样:", "\\2;11111111\\", "\\10;255\\", "\\16;FF\\", "这里有一个特殊的数字叫 NaN ,它可能出现在你没有写下数字的时候:", "\\2;22\\", - "这里没有数字显示,是因为数字2不会出现在二进制当中。 如果你想要将非数字的文本变成数字,NaN 同样会出现:", + "这里没有数字显示, 是因为数字2不会出现在二进制当中。 如果你想要将非数字的文本变成数字,NaN 同样会出现:", "\\'嗨'→#\\" ], "name": ["#", "数字"], "function": { "add": { "doc": [ - "我把自己加上一个同样 @Unit 的 @Number , 就会出现同样的 @Unit 的 @Number 。", + "我把自己加上一个同样 @Unit 的 @Number , 就会出现同样的 @Unit 的 @Number 。", "比如:", "\\1 + 1\\", "\\3只猫 + 5只猫\\", @@ -1427,7 +1617,7 @@ }, "subtract": { "doc": [ - "我把自己减去你指定的 @Number , 得出一个以同样的 @Unit 结尾的新的 @Number 。", + "我把自己减去你指定的 @Number , 得出一个以同样的 @Unit 结尾的新的 @Number 。", "比如:", "\\1 - 1\\", "\\3只猫 - 5只猫\\", @@ -1444,7 +1634,7 @@ }, "multiply": { "doc": [ - "我在我自己的基础上乘以你给我的 @Number , 得到以我的 @Unit 和指定数字的 @Unit 相结合的结果:", + "我在我自己的基础上乘以你给我的 @Number , 得到以我的 @Unit 和指定数字的 @Unit 相结合的结果:", "\\5 · 5\\", "\\5米 · 5米\\", "\\5米 · 1/秒\\" @@ -1454,7 +1644,7 @@ }, "divide": { "doc": [ - "我将自己除以你指定的 @Number , 得到以我的 @Unit 和指定数字的 @Unit 相结合的结果:", + "我将自己除以你指定的 @Number , 得到以我的 @Unit 和指定数字的 @Unit 相结合的结果:", "\\5 ÷ 5\\", "\\5米 ÷ 5米\\", "\\5米 ÷ 5秒\\" @@ -1614,22 +1804,28 @@ "inputs": [] }, "min": { - "doc": "$?", - "names": "$? min", + "doc": [ + "找到我和其他人中的最小数。", + "\\1.min(2 3 -1)\\" + ], + "names": "最小", "inputs": [ { - "doc": "$?", - "names": "$?" + "doc": "你想给我的任意数量的数字!", + "names": "数字" } ] }, "max": { - "doc": "$?", - "names": "$? max", + "doc": [ + "找到我和其他人中的最大数。", + "\\1.max(2 3 4)\\" + ], + "names": "最大", "inputs": [ { - "doc": "$?", - "names": "$?" + "doc": "你想给我的任意数量的数字!", + "names": "数字" } ] } @@ -1686,360 +1882,772 @@ } }, "List": { - "doc": "$?", - "name": "$?", - "kind": "$?", - "out": "$?", - "outofbounds": "$?", + "doc": [ + "我是一个值的序列,可以是任何类型的值!", + "你可以在我里面放任何东西:@Boolean、@Number、@Text、@None,甚至其他的@List、@Set、@Map或任何表达式。这是一个简单的例子:", + "\\['苹果' '香蕉' '芒果']\\", + "我特殊的地方在于我保持顺序,并且为所有的项从1编号。", + "我的项是有编号的,从1开始。你可以用@ListAccess获取我存储的值,使用它们的编号:", + "例如,在这个列表中,第二个值是 \\['香蕉']\\", + "\\['苹果' '香蕉' '芒果'][2]\\", + "我里面可以放任何东西。看看这个列表,包含@Text、@Number和@Time!", + "\\['苹果' 10 + 10 Time()]\\", + "当你给我很多东西的列表时,如果它们有共同的类型,我会将它们概括起来。但有时你可能确实是指的那些特定的东西。如果是的话,只需在我后面加上一个!,我会确保我只代表那些特定的值的列表。", + "\\['苹果' '香蕉' '芒果']!\\", + "大致就是这样。但是,我可以使用我的@FunctionDefinition做很多令人兴奋的事情!" + ], + "name": ["[]", "列表"], + "kind": "类型", + "out": "结果", + "outofbounds": "越界", "function": { "add": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "我创建一个包含给定项的新@List。", + "\\['苹果' '香蕉' '芒果'].add('西瓜')\\" + ], + "names": ["加"], + "inputs": [ + { + "doc": "你想要添加的值。", + "names": "项" + } + ] }, "append": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "我创建一个包含我的值以及在我后面的给定@List的所有值的新@List。", + "\\['苹果' '香蕉' '芒果'].append(['西瓜' '杨桃'])\\", + "不过,使用@Spread会更方便,像这样:", + "\\['苹果' '香蕉' '芒果' :['西瓜' '杨桃']]\\" + ], + "names": ["附加"], + "inputs": [ + { "doc": "要添加的值的列表。", "names": "列表" } + ] }, "replace": { - "doc": "$?", - "names": ["reemplazar"], + "doc": [ + "我创建一个新的列表,用给定值替换给定索引处的值。", + "\\['苹果' '香蕉' '芒果'].replace(1 '猕猴桃')\\" + ], + "names": ["替换"], "inputs": [ - { "doc": "$?", "names": "$?" }, - { "doc": "$?", "names": "$?" } + { + "doc": "要替换的值的索引。", + "names": "索引" + }, + { "doc": "替换的值", "names": "值" } ] }, - "length": { "doc": "$?", "names": "$?", "inputs": [] }, - "random": { "doc": "$?", "names": "$?", "inputs": [] }, - "first": { "doc": "$?", "names": "$?", "inputs": [] }, - "last": { "doc": "$?", "names": "$?", "inputs": [] }, + "length": { + "doc": "我里面的项数,作为@Number返回。", + "names": ["📏", "长度"], + "inputs": [] + }, + "random": { + "doc": [ + "从我的项中随机选择一个项,如果我是空的则返回@None。", + "\\['苹果' '香蕉' '芒果'].random()\\" + ], + "names": "随机", + "inputs": [] + }, + "first": { + "doc": [ + "我里面的第一个项,如果我是空的则返回@None。", + "\\['苹果' '香蕉' '芒果'].first()\\" + ], + "names": "第一个", + "inputs": [] + }, + "last": { + "doc": [ + "我里面的最后一个项,如果我是空的则返回@None。", + "\\['苹果' '香蕉' '芒果'].first()\\" + ], + "names": "最后一个", + "inputs": [] + }, "has": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "如果我里面有与给定项相等的项,则返回\\⊤\\。", + "\\['苹果' '香蕉' '芒果'].has('香蕉')\\" + ], + "names": "包含", + "inputs": [ + { "doc": "要搜索的值。", "names": "项" } + ] }, "join": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "我将我的列表中的项组合成@Text,用给定的分隔符@Text分隔。", + "\\['苹果' '香蕉' '芒果'].join(', ')\\" + ], + "names": "连接", + "inputs": [ + { + "doc": "用于分隔项的文本,可以为空。", + "names": "分隔符" + } + ] }, "subsequence": { - "doc": "$?", - "names": "$? subsequence", + "doc": [ + "我获得一个在此列表内部的列表,从你提供的索引开始,到最后一个项结束,或者如果你提供了一个,直到特定项结束。", + "\\['苹果' '香蕉' '芒果'].subsequence(2)\\", + "\\['苹果' '香蕉' '芒果'].subsequence(1 2)\\", + "看!如果你提供的数字是无序的,我会给你反向的结果", + "\\['苹果' '香蕉' '芒果'].subsequence(3 1)\\", + "如果你给我一个小于1的索引,我会认为你是指的1。", + "\\['苹果' '香蕉' '芒果'].subsequence(-1003243 2)\\", + "如果你给我一个大于最大索引的值,我会假设你指的是末尾。", + "\\['苹果' '香蕉' '芒果'].subsequence(3 2304032432)\\" + ], + "names": "子序列", "inputs": [ { - "doc": "$?", - "names": "$?" + "doc": "你想要的子序列的第一个项的索引。", + "names": "开始" }, { - "doc": "$?", - "names": "$?" + "doc": "你想要的子序列的最后一个项的索引,可选。如果你不提供,你的列表将以列表中的最后一项结束。", + "names": "结束" } ] }, "sansFirst": { - "doc": "$?", - "names": "$?", + "doc": [ + "我创建一个没有我的第一个项的@List。", + "\\['苹果' '香蕉' '芒果'].sansFirst()\\" + ], + "names": "除第一个", "inputs": [] }, - "sansLast": { "doc": "$?", "names": "$?", "inputs": [] }, - "sans": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] - }, - "sansAll": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] - }, - "reverse": { "doc": "$?", "names": "$?", "inputs": [] }, - "equals": { - "doc": "$?", - "names": ["=", "equals"], - "inputs": [{ "doc": "$?", "names": "$?" }] - }, - "notequals": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] + "sansLast": { + "doc": [ + "我创建一个没有我的最后一个项的@List。", + "\\['苹果' '香蕉' '芒果'].sansLast()\\" + ], + "names": "除最后一个", + "inputs": [] }, - "translate": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }], - "translator": [ - { "doc": "$?", "names": "$? item" }, - { "doc": "$?", "names": "$? index" }, + "sans": { + "doc": [ + "我,但是没有给定值的第一个出现。", + "\\['苹果' '香蕉' '芒果' '苹果'].sans('苹果')\\" + ], + "names": "除", + "inputs": [ { - "doc": "$?", - "names": "$?" + "doc": "要删除第一个出现的值。", + "names": "值" } ] }, - "filter": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }], - "checker": [ - { "doc": "$?", "names": "$? item" }, - { "doc": "$?", "names": "$? index" }, + "sansAll": { + "doc": [ + "我,但是没有给定值的所有出现。", + "\\['苹果' '香蕉' '芒果' '苹果'].sans('苹果')\\" + ], + "names": "全部除", + "inputs": [ { - "doc": "$?", - "names": "$?" + "doc": "要从列表中删除所有出现的值。", + "names": "值" } ] }, - "all": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }], - "checker": [ - { "doc": "$?", "names": "$? item" }, - { "doc": "$?", "names": "$? index" }, + "reverse": { + "doc": [ + "我,但是逆序!", + "\\['苹果' '香蕉' '芒果'].reverse()\\" + ], + "names": "逆序", + "inputs": [] + }, + "equals": { + "doc": [ + "如果我的项和顺序与给定的@List完全相同,则返回\\⊤\\。", + "\\['苹果' '香蕉' '芒果'] = ['苹果' '芒果' '香蕉']\\" + ], + "names": ["=", "等于"], + "inputs": [ + { + "doc": "要与我比较的@List。", + "names": "列表" + } + ] + }, + "notequals": { + "doc": [ + "如果我的项和顺序/不/与给定的@List完全相同,则返回\\⊤\\。", + "\\['苹果' '香蕉' '芒果'] ≠ ['苹果' '芒果' '香蕉']\\" + ], + "names": ["≠", "不等于"], + "inputs": [ + { + "doc": "要与我比较的@List。", + "names": "列表" + } + ] + }, + "translate": { + "doc": [ + "给我一个以值和可选索引为输入的@FunctionDefinition,产生一个值,我会在我的每个项上评估它,将我的值转化为新的值。", + "例如,假设我是@Number的列表,你想将它们都加倍:", + "\\[2 4 6 8].translate(ƒ(num•#) num · 2)\\" + ], + "names": "翻译", + "inputs": [ + { + "doc": "将转化每个项的@FunctionDefinition。", + "names": "翻译器" + } + ], + "translator": [ + { + "doc": "正在被转化的项。", + "names": "项" + }, { - "doc": "$?", - "names": "$?" + "doc": "正在被转化的项的索引。", + "names": "索引" + }, + { + "doc": "正在被转化的列表。", + "names": "列表" + } + ] + }, + "filter": { + "doc": [ + "给我一个接受一个值和可选索引作为输入并产生一个 @Boolean 值的 @FunctionDefinition,我将创建一个只包含结果为 \\⊤\\ 的新列表。", + "例如,假设我是一个 @Number 列表,你只想要其中的正数:", + "\\[2 -4 8 -16].filter(ƒ(num•#) num ≥ 0)\\" + ], + "names": "过滤器", + "inputs": [ + { + "doc": "一个 @FunctionDefinition,检查每个项目,如果应该保留,则产生 \\⊤\\。", + "names": "检查器" + } + ], + "checker": [ + { + "doc": "正在检查的项目。", + "names": "项" + }, + { + "doc": "正在检查的项目的索引。", + "names": "索引" + }, + { + "doc": "被过滤的列表。", + "names": "列表" + } + ] + }, + "all": { + "doc": [ + "给我一个 @FunctionDefinition 把一个值作为输入值并且如果它满足一些条件就产生一个@Boolean. 如果所有的物品满足条件, 我会创造一个\\⊤\\", + "例如, 想象我是一串 @Number 并且你想要去知道是不是所有数字都是正数:", + "\\[2 -4 8 -16].all(ƒ(数字•#) 数字 ≥ 0)\\" + ], + "names": "所有", + "inputs": [ + { + "doc": "@FunctionDefinition that 产生 \\⊤\\ 如果一个物品满足你的条件.", + "names": "检验员" + } + ], + "checker": [ + { + "doc": "这个物品正在被检查.", + "names": "物品" + }, + { + "doc": "这个物品的索引正在被检查.", + "names": "索引" + }, + { + "doc": "这个列表正在被检查.", + "names": "列表" } ] }, "until": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }], + "doc": [ + "给我一个@FunctionDefinition 把一个值作为输入值并且如果它满足一些条件就产生一个@Boolean. 我会创造一个包含所有物品的@List直到条件不被满足.", + "例如, 想象我是一个@Text动物的列表并且你想要所有的 东西直到\\'rat'\\被找到:", + "\\['cat' 'dog' 'rat' 'mouse' 'pony'].until(ƒ(animal•'') animal = 'rat')\\" + ], + "names": "直到", + "inputs": [ + { + "doc": "@FunctionDefinition 会产生\\⊤\\如果我应该停止包含物品.", + "names": "检验员" + } + ], "checker": [ - { "doc": "$?", "names": "$? item" }, - { "doc": "$?", "names": "$? index" }, { - "doc": "$?", - "names": "$?" + "doc": "这个物品正在被检查.", + "names": "物品" + }, + { + "doc": "这个物品的索引正在被检查.", + "names": "索引" + }, + { + "doc": "列表正在排序.", + "names": "列表" } ] }, "find": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }], + "doc": [ + "给我一个@FunctionDefinition 把一个值作为输入值并且如果它满足一些标准就产生一个@Boolean, 并且我会计算满足条件的物品.", + "例如, 想象你想要去找出第一个有这个元音\\'e'\\的动物:", + "\\['cat' 'dog' 'rat' 'mouse' 'pony'].找(ƒ(动物•'') 动物.有('e'))\\" + ], + "names": "找到", + "inputs": [ + { + "doc": "The @FunctionDefinition 如果匹配你的搜索条件, 会产生\\⊤\\.", + "names": "检验员" + } + ], "checker": [ - { "doc": "$?", "names": "$? value" }, - { "doc": "$?", "names": "$? index" }, { - "doc": "$?", - "names": "$?" + "doc": "这个物品正在被检查.", + "names": "物品" + }, + { + "doc": "这个物品的索引正在被检查.", + "names": "索引" + }, + { + "doc": "这个列表正在搜索.", + "names": "列表" } ] }, "combine": { - "doc": "$?", - "names": "$?", + "doc": [ + "给我一个接收最近一个的结合和下一个值的@FunctionDefinition, 并且创造下一个结合, 并且我将从第一个项目到最后一个项目, 创造连续的结合, 并且计算你的@FunctionDefinition 也计算的最后一个结合.", + "这对于结合在我这里的所有物品到一个单独的值非常有帮助的. 例如, 想象你要想去增加一个数字的列表:", + "\\[3 9 2 8 1 4].结合(0 ƒ(总和•# 数字•#) 总和 + 数字)\\" + ], + "names": "结合", "inputs": [ - { "doc": "$?", "names": "$?" }, - { "doc": "$?", "names": "$?" } + { + "doc": "开始的结合.", + "names": "初始的" + }, + { + "doc": "接收最新的结合和下一个值并且产生下一个结合的@FunctionDefinition.", + "names": "组合器" + } ], "combiner": [ - { "doc": "$?", "names": "$?" }, - { "doc": "$?", "names": "$?" }, - { "doc": "$?", "names": "$?" }, { - "doc": "$?", - "names": "$?" + "doc": "目前的结合", + "names": "结合" + }, + { + "doc": "下一个要结合的物品.", + "names": "下一个" + }, + { + "doc": "下一个物品的索引", + "names": "索引" + }, + { + "doc": "正在结合的列表.", + "names": "列表" } ] }, "sorted": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$", "names": "$? sequencer" }], - "sequencer": [{ "doc": "$?", "names": "$? value" }] + "doc": [ + "我可以接受一个列表, 并且创造一个值是排序好的新的列表. 像这个:", + "\\[1 5 8 0 2].排序()\\", + "我也可以为@Text 值做这个", + "\\['橙子' '猕猴桃' '香蕉' '苹果'].排序()\\", + "并且如果你有一个值既不是@Number 也不是@Text 的列表, 你可以给我把每个物品变成@Number 的@FunctionDefinition, 我就可以将它们排序. 例如, 在这里我们有一个包含不同长度列表的列表; 如果你给我一个可以将每个列表变成它的长度的功能, 我就可以将它们按长度排序.", + "\\[[1] [2 3] [4 8 12] [8]].排序(ƒ(列表) 列表.长度())\\" + ], + "names": "排序好的", + "inputs": [ + { + "doc": "可选择性使用@FunctionDefinition 来给列表的值排序. 它应该将值变成可以被用来给列表排序的@Number.", + "names": "定序器" + } + ], + "sequencer": [ + { + "doc": "变成@Number 的值.", + "names": "值" + } + ] } }, - "conversion": { "text": "$?", "set": "$?" } + "conversion": { + "text": "@Text 列表的表现.", + "set": "@Set, 对于移除重复有帮助." + } }, "Set": { - "doc": "$?", - "name": "$?", - "kind": "$?", - "out": "$?", + "doc": [ + "我是一套值! 这意味着我可以包含任何值的数字, 包括没有值. 你可以让我这样:", + "\\{1 2 3}\\", + "如果你想保存的东西没有任何副本, 我真的很好.", + "这意味着如果你给我已经有的值, 我将忽略额外的值.", + "例如, 这一套有很多重复:", + "\\{1 1 2 2 3 3}\\", + "我将它计算为只有\\{1 2 3}\\.", + "如果你想要去看我有没有一个值, @SetOrMapAccess 可以帮助:", + "\\{'罐子' '瓶子' '玻璃'}{'杯子'}\\" + ], + "name": ["{}", "指令"], + "kind": "和蔼的", + "out": "结果", "function": { "size": { - "doc": "$?", - "names": "$? size", + "doc": "我会告诉你我有几个值.", + "names": "大小", "inputs": [] }, "equals": { - "doc": "$?", - "names": ["=", "equals"], - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "我是\\⊤\\ 如果已有的@Set 和我有一摸一样的值:", + "\\{1 2 3} = {2 3 4}\\" + ], + "names": ["=", "等于"], + "inputs": [{ "doc": "拿来比较的@Set.", "names": "指令" }] }, "notequals": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "我是\\⊤\\如果已有的@Set 和我有一摸一样的值:", + "\\{1 2 3} ≠ {2 3 4}\\" + ], + "names": ["≠", "不等于"], + "inputs": [{ "doc": "拿来比较的@Set.", "names": "指令" }] }, "add": { - "doc": "$?", - "names": ["add", "+"], - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "给我一个拿来增加的值并且我会拿我的物品和给我的物品做一个新的@Set.", + "\\{1 2 3} + 4\\" + ], + "names": ["加号", "+"], + "inputs": [{ "doc": "拿来增加的物品", "names": "物品" }] }, "remove": { - "doc": "$?", - "names": ["remove", "-"], - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "给我一个拿来移除的物品并且我会产生一个没有物品的@Set.", + "\\{1 2 3} - 2\\", + "如果我没有物品, 我就只会自己算一下." + ], + "names": ["减号", "-"], + "inputs": [{ "doc": "拿来减去的物品.", "names": "物品" }] }, "union": { - "doc": "$?", - "names": ["union", "∪"], - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "给我一个@Set, 并且我会创造一个新的有我物品的@Set 和这指令的值.", + "\\{1 2 3} ∪ {3 4 5}\\" + ], + "names": ["联合", "∪"], + "inputs": [ + { + "doc": "和我结合的@Set.", + "names": "指令" + } + ] }, "intersection": { - "doc": "$?", - "names": ["intersection", "∩"], - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "给我一个@Set并且我会创造一个新的@Set, 它里面只有我们都有的物品.", + "\\{1 2 3} ∩ {3 4 5}\\" + ], + "names": ["交集", "∩"], + "inputs": [ + { "doc": "和我比较的一个指令.", "names": "指令" } + ] }, "difference": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "给我一个@Set 并且我会创造一个新的@Set, 它里面只有我们都有的物品.", + "\\{1 2 3}.difference({3 4 5})\\" + ], + "names": "不同", + "inputs": [ + { + "doc": "这套的物品应该从我这里移除的物品.", + "names": "套" + } + ] }, "filter": { - "doc": "$?", - "names": "filter", - "inputs": [{ "doc": "$?", "names": "$? checker" }], + "doc": [ + "给我一个可以接收物品并且产生\\⊤\\的@FunctionDefinition, 如果它应该被保留, 我会创造一个只包含可以满足你要求的物品的@Set.", + "例如, 让我们找出我这里的奇数:", + "\\{1 2 3 4 5 6 7 8 9}.过滤(ƒ(数字•#) (数字 % 2) = 1)\\" + ], + "names": "过滤", + "inputs": [ + { + "doc": "检查物品是否需要被保留的@FunctionDefinition.", + "names": "检验员" + } + ], "checker": [ - { "doc": "$?", "names": "$? value" }, { - "doc": "$?", - "names": "$? set" + "doc": "正在被检查的物品.", + "names": "值" + }, + { + "doc": "被过滤的套", + "names": "指令" } ] }, "translate": { - "doc": "$?", - "names": "translate", - "inputs": [{ "doc": "$?", "names": "$? translator" }], + "doc": [ + "给我一个可以接收物品并且可以产生新的物品的@FunctionDefinition, 之后我会翻译我的所有物品到新的@Set (移除任何的重复).", + "例如, 让我们把所有的@Number变成@Text:", + "\\{1 2 3 4 5 6 7 8 9}.translate(ƒ(数字•#) 数字→'')\\" + ], + "names": "翻译", + "inputs": [ + { + "doc": "可以将我其中一个物品翻译成你想要的新物品的@FunctionDefinition.", + "names": "指令" + } + ], "translator": [ - { "doc": "$?", "names": "$? value" }, { - "doc": "$?", - "names": "$? set" + "doc": "正在被翻译的物品.", + "names": "值" + }, + { + "doc": "正在被翻译的值", + "names": "指令" } ] } }, - "conversion": { "text": "$?", "list": "$?" } + "conversion": { + "text": "@Set 的体现@Text", + "list": "在指令里面的物品的代表@List." + } }, "Map": { - "doc": "$?", - "name": "$?", - "key": "$?", - "value": "$?", - "result": "$?", + "doc": [ + "我将值放在一起, 映射*密钥*到*值*. 例如:", + "\\{'艾米': 6分 '托尼':3分 '希拉': 8分}\\", + "我的密钥可以是任何类型的值, 我的值也可以是任何类型的值.", + "一些人喜欢把我想成索引, 或者是目录, 你可以给我一些东西的地方, 并且我给你映射过的.", + "如果你想要检查映射过的东西, 你可以用@SetOrMapAccess, 一个密钥并且它们会给你值:", + "\\{'艾米': 6分 '托尼':3分 '希拉': 8分}{'艾米'}\\", + "如果这里没有匹配的密钥, 我会给你显示@None.", + "\\{'艾米': 6分 '托尼':3分 '希拉': 8分}{'詹'}\\", + "你也可以做一个空的映射, 就像这样:", + "\\{:}\\", + "我知道和我的匹配可以创造出多少美好的事情." + ], + "name": ["{:}", "映射"], + "key": "密钥", + "value": "值", + "result": "结果", "function": { "size": { - "doc": "$?", - "names": "$? size", + "doc": "我会告诉你我有多少值.", + "names": "大小", "inputs": [] }, "equals": { - "doc": "$?", - "names": ["=", "equals"], - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "\\{⊤}\\ 如果我的匹配和给出的@Map 一摸一样.", + "\\{1:1 2:2} = {1:1 2:3}\\" + ], + "names": ["=", "等于"], + "inputs": [ + { + "doc": "比较我的@Map.", + "names": "值" + } + ] }, "notequals": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "\\{⊤}\\ 如果我的匹配并/不是/ 和给出的@Map的 一摸一样.", + "\\{1:1 2:2} ≠ {1:1 2:3}\\" + ], + "names": ["≠", "不等于"], + "inputs": [ + { + "doc": "和我比较的@Map.", + "names": "值" + } + ] }, "set": { - "doc": "$?", - "names": "$?", + "doc": [ + "我会创造一个新的@Map, 它有一样的配对, 但是有你给我的新的配对. 如果我已经有密钥, 我会将它配对到新的值.", + "\\{'艾米': 6分 '托尼':3分}.匹配('詹' 0分)\\" + ], + "names": "配对", "inputs": [ - { "doc": "$?", "names": "$?" }, - { "doc": "$?", "names": "$?" } + { "doc": "匹配值的密钥.", "names": "密钥" }, + { + "doc": "和密钥匹配的值", + "names": "值" + } ] }, "unset": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "我会创造一个没有你给我密钥的@Map, 移除配对.", + "\\{'艾米': 6分 '托尼':3分}.不匹配('艾米')\\" + ], + "names": "不匹配", + "inputs": [{ "doc": "忘记的密钥.", "names": "密钥" }] }, "remove": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$?" }] + "doc": [ + "我会创造一个新的没有任何密钥的@Map, 这些密钥是没有值的.", + "\\{'艾米': 0分 '詹': 0分 '托尼':3分}.移除(0分)\\" + ], + "names": "移除", + "inputs": [ + { + "doc": ".", + "names": "值" + } + ] }, "filter": { - "doc": "$?", - "names": "filter", - "inputs": [{ "doc": "$?", "names": "$? checker" }], + "doc": [ + "给我一个可以接收密钥和值的@FunctionDefinition 计算\\⊤\\ 如果一个配对应该被保留. 我会创造一个新的可以满足你要求的@Map.", + "例如, 在这里我想要去保留任何Amy的活着有高于0分的配对.", + "\\{'艾米': 0分 '詹': 0分 '托尼':3分}.过滤(ƒ(密钥•'' 值•#分) (密钥 = '艾米') | (值 > 0分))\\" + ], + "names": "过滤", + "inputs": [ + { + "doc": "可以决定是否保留一个配对的@FunctionDefinition.", + "names": "检验员" + } + ], "checker": [ - { "doc": "$?", "names": "$? key" }, - { "doc": "$?", "names": "$? value" }, - { "doc": "$?", "names": "$?" } + { "doc": "正在被检查的密钥.", "names": "密钥" }, + { + "doc": "正在被检查的值.", + "names": "值" + }, + { + "doc": "正在被过滤的密钥.", + "names": "映射" + } ] }, "translate": { - "doc": "$?", - "names": "translate", - "inputs": [{ "doc": "$?", "names": "$? translator" }], + "doc": [ + "可以接收密钥和值的@FunctionDefinition, 并且计算值到一个新的值. 我会创造一个新的带着一样密钥的但是更新过值的@Map.", + "例如, 让我们给每个人一分自从他们一直表现的很好.", + "\\{'艾米': 5分 '詹': 3分 '托尼': 0分}.翻译(ƒ(密钥•'' 值•#分数) 值 + 1分数)\\" + ], + "names": "翻译", + "inputs": [ + { + "doc": "翻译每个值的@FunctionDefinition.", + "names": "翻译家" + } + ], "translator": [ - { "doc": "$?", "names": "$? key" }, - { "doc": "$?", "names": "$? value" }, - { "doc": "$?", "names": "$?" } + { + "doc": "正在被翻译的值的密钥.", + "names": "密钥" + }, + { + "doc": "正在被翻译的值.", + "names": "值" + }, + { + "doc": "正在被翻译的映射", + "names": "映射" + } ] } }, - "conversion": { "text": "$?", "set": "$?", "list": "$?" } + "conversion": { + "text": "映射的代表@Text.", + "set": "@Map 的密钥", + "list": "一个在带有值的@Map 里面带有值的列表" + } }, "Table": { - "doc": "$?", - "name": "$?", - "row": "$?", + "doc": [ + "我是一组表行! 我可以帮助你跟踪具有相同结构的值的大型集合.", + "例如, 想象你想要去追踪一大堆石头:", + "\\⎡名字•'' 颜色•''⎦\n⎡'黑曜石' '黑色'⎦\n⎡'浮岩' '灰色'⎦\n⎡'黄水晶' '黄色'⎦\\", + "@Bind 可以帮助你命名它! 并且之后你可以做这些事情,例如, 做一个有新的行@Insert 的修正过的数据库:", + "\\石头: ⎡名字•'' 颜色•''⎦\n⎡'黑曜石' '黑色'⎦\n⎡'浮岩' '灰色'⎦\n⎡'黄水晶' '黄色'⎦\n石头 ⎡+ '石英' '白色'⎦\\", + "或者如果你想要去找出可以符合的行, 你可以用@Select 可以符合条件的行:", + "\\石头: ⎡名字•'' 颜色•''⎦\n⎡'黑曜石' '黑色'⎦\n⎡'浮岩' '灰色'⎦\n⎡'黄水晶' '黄色'⎦\n石头 ⎡?⎦ 颜色 = '灰色'\\", + "或者如果你想要做一个修正过的数据库, 这个数据库对于可以满足条件的行有不同的值:", + "\\石头: ⎡名字•'' 颜色•''⎦\n⎡'黑曜石' '黑色'⎦\n⎡'浮岩' '灰色'⎦\n⎡'黄水晶' '黄色'⎦\n石头 ⎡: 颜色: '黑色' ⎦ name = '浮岩'\\", + "或者你可能想要删掉可以满足条件的行:", + "\\石头: ⎡名字•'' 颜色•''⎦\n⎡'黑曜石' '黑色'⎦\n⎡'浮岩' '灰色'⎦\n⎡'黄水晶' '黄色'⎦\n石头 ⎡- 名字.有('i')\\", + "并且如果你想从我这里得到具体的值, 你可以把任何一个数据库转换成一个列表, 并且可以用@PropertyReference 访问单独的行.", + "\\石头: ⎡名字•'' 颜色•''⎦\n⎡'黑曜石' '黑色'⎦\n⎡'浮岩' '灰色'⎦\n⎡'黄水晶' '黄色'⎦\n(石头 → [])[1].名字\\" + ], + "name": ["⎡⎦", "工作台"], + "row": "排", "function": { "equals": { - "doc": "$?", - "names": "$? equals", - "inputs": [{ "doc": "$?", "names": "$? value" }] + "doc": "我如果我有和另一个@Table一样的以同样顺序排列的单元, 我会检查.", + "names": ["=", "等于"], + "inputs": [{ "doc": "检查的另一个工作台.", "names": "值" }] }, "notequal": { - "doc": "$?", - "names": "$?", - "inputs": [{ "doc": "$?", "names": "$? value" }] + "doc": "如果和另一个@Table 比较起来, 任何我的单元是不同的或者以一个不同的顺序排列, 我会检查.", + "names": ["≠", "不相等"], + "inputs": [{ "doc": "检查的另一个工作台.", "names": "值" }] } }, "conversion": { - "list": "$?", - "text": "$?" + "list": "我把一个@Table转换成一个含有行的列表, 这个列表的每一行是@Structure而且它的列的名字是它的参数.", + "text": "我就是把一个@Table转换成文字." } }, "Structure": { - "doc": "$?", - "name": "$?", + "doc": "看@StructureDefinition.", + "name": ["结构"], "function": { "equals": { - "doc": "$?", - "names": "$? =", + "doc": "如果我的参数与另外一个结构的参数是同样的名字和值, 我会检查.", + "names": ["=", "等于"], "inputs": [ { - "doc": "$?", - "names": "$? value" + "doc": "另一个要检查的结构.", + "names": "值" } ] }, "notequal": { - "doc": "$?", - "names": "$? ≠", + "doc": "如果我的参数和另外一个结构的参数有任何的名字和值上面的不同, 我会检查.", + "names": ["≠", "不等于"], "inputs": [ { - "doc": "$?", - "names": "$? value" + "doc": "另一个要检查的结构.", + "names": "值" } ] } }, "conversion": { - "text": "$?" + "text": "我把我自己转换成@Text." } } }, @@ -2047,10 +2655,10 @@ "Random": { "doc": [ "17!", - "/@方法的定义在这路, 我会解释这个./", - "所以 @随机 是一个充满好奇心的生成随机数的方法 他很好奇,因为每次你评估它时,它都会创造出不同的东西。", + "/@FunctionDefinition, 我会解释这个./", + "所以 @Random 是一个充满好奇心的生成随机数的方法 他很好奇,因为每次你评估它时,它都会创造出不同的东西。", "这造成了一种奇妙的混乱,并伴随着不可预测性。", - "在默认情况下, 他会给出 @数字类型 在 \\0\\ 和 \\1\\之间的值:", + "在默认情况下, 他会给出 @Number 类型 在 \\0\\ 和 \\1\\之间的值:", "\\随机()\\", "但是你可以给他输入一个参数, 他就会生成一个在\\0\\ 和那个参数之间的值:", "\\随机(10)\\", @@ -2070,7 +2678,7 @@ "Choice": { "doc": [ "/clickety tap!/", - "/@这是方法定义, 我来解释下这个吧!/", + "/@FunctionDefinition, 我来解释下这个吧!/", "将 @Choice 视为由受众选择的 @Phrase/name 流。如果有人在带有名称的 @Phrase 上单击、敲击或按 /Enter/ 进行键盘选择,@Choice 将有一个与名称匹配的新值。", "因此,使用它的最佳方法是使用命名的可选短语@Phrase 创建一个表演,然后使用@Reaction 来决定选择该名称时要执行的操作。", "这里有一个简单的例子:", @@ -2119,7 +2727,7 @@ "对于特殊的键,如/Escape/键,将使用@Text描述键,使用<预定义名称@https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values>,不幸的是只有英文版本。", "如果你只想知道一个特定的密钥,你可以提供它:", "\\Key('a')\\", - "如果你只想知道@Key什么时候被释放而不是按下,你可以提供一个@布尔值:", + "如果你只想知道@Key什么时候被释放而不是按下,你可以提供一个@Boolean值:", "\\Key('a' ⊥)\\" ], "names": ["⌨️", "钥匙"], @@ -2207,12 +2815,12 @@ "看到0是如何反弹的了吗?在第一次评估时,我们给它一个@Stage的高位置,但之后,它得到@None,这允许@Motion将其更改为重力将其放置的任何位置。", "查看下面配置它的许多其他方法" ], - "place": { "doc": "开始点", "names": " place" }, - "velocity": { "doc": "初始速度", "names": " velocity" }, - "nextplace": { "doc": "下一地点,无视物理", "names": " nextplace" }, + "place": { "doc": "开始点", "names": "点" }, + "velocity": { "doc": "初始速度", "names": "速度" }, + "nextplace": { "doc": "下一地点,无视物理", "names": "下一地点" }, "nextvelocity": { "doc": "下一地点,无视速度", - "names": " nextvelocity" + "names": " 下一个速度" } }, "Chat": { @@ -2268,7 +2876,7 @@ "\\Webpage('https://wordplay.dev')\\", "而且显然有一种东西叫做 , 它想让你在网页上查询东西?给我们一个CSS选择查询,我们将只获得与该查询匹配的文本。就像这个例子,它获得一级标头", "\\Webpage('https://wordplay.dev' 'h1')\\", - "这款手机可能会出很多问题。如果你失去了互联网连接,或者URL不能解析任何东西,或者URL不是公开的,或者URL不是HTML页面……所有这些都可能导致异常。如果你找到一个合适的页面,你会得到一个@数字,表示完成百分比,然后是一个@页面上的单词列表。" + "这款手机可能会出很多问题。如果你失去了互联网连接,或者URL不能解析任何东西,或者URL不是公开的,或者URL不是HTML页面……所有这些都可能导致异常。如果你找到一个合适的页面,你会得到一个@Number,表示完成百分比,然后是一个@List的单词页面。" ], "names": ["🔗", "网页"], "url": { "doc": "要获取的HTML网页URL。", "names": " url" }, @@ -2305,18 +2913,18 @@ } }, "Rebound": { - "names": "回弹Rebound", - "doc": "我来自@Collision,代表谁被碰撞了,碰撞发生在哪个方向。用我来决定是否以某种特殊的方式对碰撞做出反应,而不是普通的物理反应。", + "names": "回弹", + "doc": "我来自 @Collision,代表谁被碰撞了,碰撞发生在哪个方向。用我来决定是否以某种特殊的方式对碰撞做出反应,而不是普通的物理反应。", "direction": { - "names": "$? direction", + "names": "方向", "doc": "碰撞的方向和大小,相对于碰撞的主体" }, "subject": { - "names": "主观subject", + "names": "主观", "doc": "主观所命中的输出的名称" }, "object": { - "names": "客观object", + "names": "客观", "doc": "击中主题的输出的名称" } }, @@ -2335,72 +2943,23 @@ }, "output": { "Output": { - "names": "输出 Output", - "doc": "我不是你真正可以制作的@结构定义。但我是一个非常重要的人,因为我激发了我们舞蹈中最重要的元素:@短语、@组和@舞台。去见见他们,去了解更多关于如何使用它们的信息。" - }, - "Stage": { - "names": "$?", - "doc": "$?", - "description": "$?", - "content": { "doc": "$?", "names": "$?" }, - "frame": { "doc": "$?", "names": "$?" }, - "size": { "doc": "$?", "names": "$?" }, - "face": { "doc": "$?", "names": "$?" }, - "place": { "doc": "$?", "names": "$?" }, - "name": { "doc": "$?", "names": "$?" }, - "selectable": { "doc": "$?", "names": "$?" }, - "color": { - "doc": "$?", - "names": "$? color" - }, - "background": { "doc": "$?", "names": "$? background" }, - "opacity": { - "doc": "$?", - "names": "$? opacity" - }, - "offset": { - "doc": "$?", - "names": "$? offset" - }, - "rotation": { - "doc": "$?", - "names": "$? rotation" - }, - "scale": { - "doc": "$?", - "names": "$? scale" - }, - "flipx": { - "doc": "$?", - "names": "$? flipx" - }, - "flipy": { - "doc": "$?", - "names": "$? flipy" - }, - "entering": { "doc": "$?", "names": "$?" }, - "resting": { "doc": "$?", "names": "$?" }, - "moving": { "doc": "$?", "names": "$?" }, - "exiting": { "doc": "$?", "names": "$?" }, - "duration": { "doc": "$?", "names": ["$?"] }, - "style": { "doc": "$?", "names": "$?" }, - "gravity": { "doc": "$?", "names": "$? gravity" } + "names": "输出", + "doc": "我不是你真正可以制作的 @StructureDefinition 定义。但我是一个非常重要的人,因为我激发了我们舞蹈中最重要的元素:@Phrase、@Group 和 @Stage。去见见他们,去了解更多关于如何使用它们的信息。" }, "Group": { - "names": "组", - "doc": "哦你好,你过的怎么样?当有其他人在身边时,我总是很愉快,所以能和你在一起真是太好了!\n 我将@短语和@组组合在一起放在@舞台上,并将它们放在@整理中,这样它们的位置就有了一些秩序。\n 要使我工作,你需要给我一个@整理,然后是一个@输出的@列表以进行安排。\n 例如,在这里我用了一个@堆栈排列和一些垂直堆叠的@短语:\n \\组(堆栈() [短语('第一个') 短语('第二个')])\\ \n 我如何安排事物取决于你给我的@整理。", - "description": "$1[$1|] $2 $3", - "content": { - "doc": "安排的@输出列表。", - "names": "内容" - }, + "doc": "哦你好,你过的怎么样?当有其他人在身边时,我总是很愉快,所以能和你在一起真是太好了!\n 我将 @Phrase 和 @Group 组合在一起放在 @Stage上,并将它们放在@Arrangement中,这样它们的位置就有了一些秩序。\n 要使我工作,你需要给我一个@Arrangement,然后是一个@Output的@List以进行安排。\n 例如,在这里我用了一个@Stack Arrnagement和一些垂直堆叠的@Phrase:\n \\组(堆栈() [短语('第一个') 短语('第二个')])\\ \n 我如何安排事物取决于你给我的 @Arrangement。", + "names": ["🔳", "组合"], "layout": { - "doc": "将@输出放置在其位置的安排方式。", + "doc": "将 @Output 放置在其位置的安排方式。", "names": "布局" }, + "content": { + "doc": "安排的 @Output 列表。", + "names": "内容" + }, "matter": { "doc": "如果我不小心碰到其他物体,我应该如何反应。", - "names": "物体 matter" + "names": "物体" }, "size": { "doc": "我内心里美好的内容应该有多高,除非它们有自己的尺寸!", @@ -2414,75 +2973,105 @@ "doc": "舞台上我应该在的位置。 我内部的内容会相对于那里进行排列。", "names": "位置" }, - "name": { "doc": "与@短语/名称相同!", "names": "名称" }, + "name": { + "doc": "与 @Phrase/name 相同!", + "names": "名称" + }, "selectable": { - "doc": "与@短语/可选择的相同! ", + "doc": "与 @Phrase/selectable 的相同! ", "names": "可选择的" }, "color": { - "doc": "我内部的内容应该是@颜色,除非它们有自己的颜色。", - "names": "颜色 color" + "doc": "我内部的内容应该是 @Color,除非它们有自己的颜色。", + "names": "颜色" }, "background": { - "doc": "投影在我背后的@颜色。", - "names": "背景 background" + "doc": "投影在我背后的 @Color。", + "names": "背景" }, "opacity": { - "doc": "我体内的一切在 \\0\\ 和 \\1\\ 之间应该是多么透明,除非被不同的@姿势覆盖。", - "names": "透明 opacity" + "doc": "我体内的一切在 \\0\\ 和 \\1\\ 之间应该是多么透明,除非被不同的 @Pose 覆盖。", + "names": "透明" }, "offset": { - "doc": "一个 @位置 指示它与我的正常 @位置 的偏移量,除非被不同的 @姿势 覆盖。 有助于就地摆动。", - "names": "抵消 offset" + "doc": "一个 @Place 指示它与我的正常 @Place 的偏移量,除非被不同的 @Pose 覆盖。 有助于就地摆动。", + "names": "抵消" }, "rotation": { - "doc": "我应该围绕我的中心倾斜多少,我的@姿势有不同的倾斜。", - "names": "自转 rotation" + "doc": "我应该围绕我的中心倾斜多少,我的 @Pose 有不同的倾斜。", + "names": ["📐", "自转"] }, "scale": { "doc": "相对于我原来的尺寸我应该有多大。", - "names": "比例 scale" + "names": "比例" }, "flipx": { - "doc": "与@短语/水平翻转相同!", - "names": "水平翻转 flipx" + "doc": "与 @Phrase/flipx 翻转相同!", + "names": "水平翻转" }, "flipy": { - "doc": "与@短语/垂直翻转相同!", - "names": "垂直翻转flipy" + "doc": "与 @Phrase/flipy 相同!", + "names": "垂直翻转" + }, + "entering": { + "doc": "与 @Phrase/entering 相同!", + "names": "进入" + }, + "resting": { + "doc": "与 @Phrase/resting 相同!", + "names": "休息" + }, + "moving": { + "doc": "与 @Phrase/moving 相同!", + "names": "移动" + }, + "exiting": { + "doc": "与 @Phrase/exiting 相同!", + "names": "退出" }, - "entering": { "doc": "与@短语/进入相同!", "names": "进入" }, - "resting": { "doc": "与@短语/休息相同!", "names": "休息" }, - "moving": { "doc": "与@短语/移动相同!", "names": "移动" }, - "exiting": { "doc": "与@短语/退出相同!", "names": "退出" }, "duration": { - "doc": "与@短语/持续时间相同!", - "names": ["持续时间"] + "doc": "与 @Phrase/duration 相同!", + "names": ["⏳", "持续时间"] }, - "style": { "doc": "与@短语/风格相同!", "names": "风格" } + "style": { + "doc": "与 @Phrase/style 相同!", + "names": "风格" + }, + "description": "$1[$1|] $2 $3" }, "Phrase": { - "names": ["💬", "Frase"], - "doc": "你好,你好!还记得我吗?怎么会有人忘记/我/。没错,我就是伟大的@短语,准备好在@舞台上表达最可爱的@文字。\n 只要让我这样,我就会出现在@舞台:\n \\短语('太棒了!')\\ \n 显然,我需要一些 @文字,但除此之外,我可以做任何@输出可以做的所有事情,包括更改我的大小、字体、旋转,以及使用@姿势和@顺序进行所有令人难以置信的舞蹈。 \n 你也可以在@舞台上选择我,然后在隔壁的调色板上编辑我。", - "text": { "doc": "在@舞台上展示的角色。", "names": "文字" }, - "description": "$3[$3 米 |]短语 $1 $2[命名 $2|] $4[$4|] $5", - "size": { "doc": "我应该多高,以米为单位!", "names": "尺寸" }, - "face": { "doc": "我应该使用的字体名称。", "names": "表面" }, - "place": { "doc": "舞台上我应该在的地方。", "names": "位置" }, + "doc": "你好,你好!还记得我吗?怎么会有人忘记/我/。没错,我就是伟大的 @Phrase,准备好在 @Stage 上表达最可爱的 @Text。\n 只要让我这样,我就会出现在 @Stage:\n \\短语('太棒了!')\\ \n 显然,我需要一些 @Text,但除此之外,我可以做任何 @Output 可以做的所有事情,包括更改我的大小、字体、旋转,以及使用 @Pose 和 @Sequence 进行所有令人难以置信的舞蹈。 \n 你也可以在 @Stage 上选择我,然后在隔壁的调色板上编辑我。", + "names": ["💬", "短语"], + "text": { + "doc": "在 @Stage 上展示的角色。", + "names": "文字" + }, + "size": { + "doc": "我应该多高,以米为单位!", + "names": "尺寸" + }, + "face": { + "doc": "我应该使用的字体名称。", + "names": "表面" + }, + "place": { + "doc": "舞台上我应该在的地方。", + "names": "位置" + }, "wrap": { "doc": "我应该包裹符号的边缘,或者 \\ø\\ 如果我不应该包裹它们。", - "names": "包裹 wrap" + "names": ["↵","包裹"] }, "alignment": { - "doc": "如果有@舞台/包裹的边界集,我是否应该将符号与边缘的开始、中心或结束对齐。", - "names": "对齐 alignment" + "doc": "如果有 @Phrase/wrap 的边界集,我是否应该将符号与边缘的开始、中心或结束对齐。", + "names": "对齐" }, "matter": { "doc": "碰到东西时可以使用的属性!", - "names": "物体 matter" + "names": "物体" }, "name": { - "doc": "你给我起一个名字!这对很多事情都有帮助。\n 首先,如果我有名字,我会用它在屏幕阅读器描述中描述自己。\n 第二,在制作动画时,您可能有多个不同的表达式,这些表达式应该在舞台上表示相同的内容;给它们相同的名称,它们就会作为一个动画。 \n 最后,我对 @选择很有帮助:你给我的名字出现在该信息流中。 \n 如果有帮助的话,您可以给我许多不同的名称,每个名称都采用不同的语言。我将始终在第一个选定的区域设置中使用该名称", + "doc": "你给我起一个名字!这对很多事情都有帮助。\n 首先,如果我有名字,我会用它在屏幕阅读器描述中描述自己。\n 第二,在制作动画时,您可能有多个不同的表达式,这些表达式应该在舞台上表示相同的内容;给它们相同的名称,它们就会作为一个动画。 \n 最后,我对 @Choice 很有帮助:你给我的名字出现在该信息流中。 \n 如果有帮助的话,您可以给我许多不同的名称,每个名称都采用不同的语言。我将始终在第一个选定的区域设置中使用该名称", "names": "名字" }, "selectable": { @@ -2490,148 +3079,221 @@ "names": "可选择的" }, "color": { - "doc": "@颜色应该是默认的,除非被不同的@姿势覆盖。", - "names": "颜色 color" + "doc": "@Color 应该是默认的,除非被不同的 @Pose 覆盖。", + "names": "颜色" }, "background": { - "doc": "投射在我身后的@颜色", - "names": "背景 background" + "doc": "投射在我身后的 @Color", + "names": "背景" }, "opacity": { - "doc": "默认情况下我应该有多透明,在 \\0\\ 和 \\1\\ 之间,除非被不同的@姿势覆盖。有助于淡入和淡出。", - "names": "透明 opacity" + "doc": "默认情况下我应该有多透明,在 \\0\\ 和 \\1\\ 之间,除非被不同的 @Pose 覆盖。有助于淡入和淡出。", + "names": "透明" }, "offset": { - "doc": "一个@位置指示它与我的@位置的偏移量,除非被不同的@姿势覆盖。 有助于就地摆动。", - "names": "抵消 offset" + "doc": "一个 @Place 指示它与我的 @Place 的偏移量,除非被不同的 @Pose 覆盖。 有助于就地摆动。", + "names": "抵消" }, "rotation": { - "doc": "我应围绕其中心旋转的度数,除非被不同的@姿势覆盖。", - "names": "自转 rotation" + "doc": "我应围绕其中心旋转的度数,除非被不同的 @Pose 覆盖。", + "names": "自转" }, "scale": { - "doc": "我应该相对于其原始大小放大多少,除非被不同的@姿势覆盖。", - "names": "比例 scale" + "doc": "我应该相对于其原始大小放大多少,除非被不同的 @Pose 覆盖。", + "names": "比例" }, "flipx": { - "doc": "我是否应该在x轴上镜像,除非被不同的@姿势覆盖。", - "names": "水平翻转 flipx" + "doc": "我是否应该在x轴上镜像, 除非被不同的 @Pose 覆盖。", + "names": "水平翻转" }, "flipy": { - "doc": "我是否应该在y轴上镜像,除非被不同的@姿势覆盖。", - "names": "垂直翻转 flipy" + "doc": "我是否应该在y轴上镜像, 除非被不同的 @Pose 覆盖。", + "names": "垂直翻转" }, "entering": { - "doc": "上台时我应该做的@姿势或@顺序", + "doc": "上台时我应该做的 @Pose 或 @Sequence", "names": "进入" }, "resting": { - "doc": "我应该在进入舞台之后、退出之前以及我的@位置没有改变的情况下执行@姿势或@顺序。 如果您不给我,我将使用默认值。", + "doc": "我应该在进入舞台之后、退出之前以及我的@Place没有改变的情况下执行 @Pose 或 @Sequence。 如果您不给我,我将使用默认值。", "names": "休息" }, "moving": { - "doc": "在舞台上移动位置时我应该执行的@姿势或@顺序,而不是我的默认设置。", + "doc": "在舞台上移动位置时我应该执行的 @Pose 或 @Sequence,而不是我的默认设置。", "names": "移动" }, "exiting": { - "doc": "@姿势或@顺序应该在退出阶段之前执行。", + "doc": "@Pose 或 @Sequence应该在退出阶段之前执行。", "names": "退出" }, "duration": { "doc": "移动到舞台上不同位置时适用的持续时间。", - "names": ["持续时间"] + "names": ["⏳","持续时间"] }, "style": { "doc": "移动到舞台上不同位置时使用的动画风格。", "names": "风格" - } + }, + "description": "$3[$3 米 |]短语 $1 $2[命名 $2|] $4[$4|] $5" + }, + "Arrangement": { + "doc": "我是Verse中各种排列方式的灵感, 包括@Row、@Stack、@Grid和@Free。我与@Group密切合作,", + "names": ["⠿", "排列"] }, - "Arrangement": { "names": ["Arrangement"], "doc": "$?" }, "Row": { - "names": ["Fila"], - "doc": "$?", - "description": "$?", + "doc": "我是@Row, 一个水平的@Arrangement,包含@Output,中间可以添加可选的填充。你见过我的孪生兄弟@Stack吗?", + "names": ["➡", "行"], + "description": "$1个短语和组的行", "alignment": { - "doc": "$?", - "names": "$? alignment" + "doc": "是否在每列上的起始、中间或末尾对齐文本。", + "names": "对齐" }, - "padding": { "doc": "$?", "names": "$?" } + "padding": { + "doc": "在输出之间放置的填充量。", + "names": "填充" + } }, "Stack": { - "names": "$?", - "doc": "$?", - "description": "$?", - "padding": { "doc": "$?", "names": "$?" }, + "doc": "我是@Stack,一个垂直的@Arrangement,包含@Output,中间可以添加可选的填充。你见过我的孪生兄弟@Row吗?", + "names": ["⬇", "堆叠"], + "description": "$1个短语和组的堆叠", "alignment": { - "doc": "$?", - "names": "$? alignment" + "doc": "是否在每行上的起始、中间或末尾对齐文本。", + "names": "对齐" + }, + "padding": { + "doc": "在输出之间放置的填充量。", + "names": "填充" } }, "Grid": { - "names": "$?", - "doc": "$?", - "description": "$?", - "rows": { "doc": "$?", "names": "$?" }, - "columns": { "doc": "$?", "names": "$?" }, - "padding": { "doc": "$?", "names": "$?" }, - "cellWidth": { "doc": "$?", "names": "$?" }, - "cellHeight": { "doc": "$?", "names": "$?" } + "doc": "我是@Output的网格。告诉我行数和列数,我将制作一个整齐的排列,可选的填充和单元格大小。", + "names": ["▦", "网格"], + "description": "$1行$2列的网格", + "rows": { + "doc": "网格中的行数。", + "names": "行数" + }, + "columns": { + "doc": "网格中的列数。", + "names": "列数" + }, + "padding": { + "doc": "在单元格之间放置的填充量。", + "names": "填充" + }, + "cellWidth": { + "doc": "单元格应有多宽。", + "names": "单元格宽度" + }, + "cellHeight": { + "doc": "单元格应有多高。", + "names": "单元格高度" + } }, "Free": { - "names": "$?", - "doc": "$?", - "description": "$?" + "doc": [ + "我随便怎么样。随便坐在哪里都行。只要坐在某个地方!确保你给我所有的@Output都有一个@Place,否则它们就不知道该去哪里。", + "哦,记住,你给每个@Output的@Place都是相对于@Group的@Place!所以如果你想知道为什么事情没有出现在你期望的地方,尝试给@Group也设置一个地方。" + ], + "names": ["自由"], + "description": "自由形式的$1输出" }, "Shape": { - "names": "$? shape", - "doc": "$?", - "form": { "doc": "$?", "names": "$? form" }, - "name": { "doc": "$?", "names": "$? name" }, - "selectable": { "doc": "$?", "names": "$? selectable" }, + "doc": "我是所有形状的灵感。我用于告诉@Stage应该是什么形状。", + "names": ["⬟", "形状"], + "form": { + "doc": "我是要显示的形状种类。每种形状需要不同的信息来定义其排列。", + "names": "形状" + }, + "name": { + "doc": "我是你可以使用的名称,用于动画和@Collision。例如,如果代表地面,你可能想叫我'地面'。", + "names": "名称" + }, + "selectable": { + "doc": "是否可以作为@Choice的一部分选择。", + "names": "可选择性" + }, "color": { - "doc": "$?", - "names": "$? color" + "doc": "我的边框颜色。", + "names": "颜色" + }, + "background": { + "doc": "我的背景颜色。", + "names": "背景" }, - "background": { "doc": "$?", "names": "$? background" }, "opacity": { - "doc": "$?", - "names": "$? opacity" + "doc": "我应该有多透明。", + "names": "透明度" }, "offset": { - "doc": "$?", - "names": "$? offset" + "doc": "我应该距离我的位置多远出现,同时保持在原地。", + "names": "偏移" }, "rotation": { - "doc": "$?", - "names": "$? rotation" + "doc": "我应该旋转多少。这会影响@Collision。", + "names": "旋转" }, "scale": { - "doc": "$?", - "names": "$? scale" + "doc": "我应该放大多少,而不改变我的实际大小。", + "names": "缩放" }, "flipx": { - "doc": "$?", - "names": "$? flipx" + "doc": "是否在x轴上镜像我。", + "names": "水平翻转" }, "flipy": { - "doc": "$?", - "names": "$? flipy" + "doc": "是否在y轴上镜像我。", + "names": "垂直翻转" + }, + "entering": { + "doc": "我进入@Stage时应该执行的@Pose或@Sequence。", + "names": "进入时" + }, + "resting": { + "doc": "我进入并且不移动时应该执行的@Pose或@Sequence。", + "names": "静止时" + }, + "moving": { + "doc": "我移动位置时应该执行的@Pose或@Sequence。", + "names": "移动时" + }, + "exiting": { + "doc": "我离开@Stage时应该执行的@Pose或@Sequence。", + "names": "离开时" + }, + "duration": { + "doc": "如果是单个@Pose,我的动画应该持续多长时间。", + "names": "持续时间" }, - "entering": { "doc": "$?", "names": "$? entering" }, - "resting": { "doc": "$?", "names": "$? resting" }, - "moving": { "doc": "$?", "names": "$? moving" }, - "exiting": { "doc": "$?", "names": "$? exiting" }, - "duration": { "doc": "$?", "names": ["$? duration"] }, - "style": { "doc": "$?", "names": "$? style" } + "style": { + "doc": "我应该使用的动画样式。", + "names": "样式" + } }, "Rectangle": { - "names": "$?", - "doc": "$?", - "left": { "doc": "$?", "names": "$?" }, - "top": { "doc": "$?", "names": "$?" }, - "right": { "doc": "$?", "names": "$?" }, - "bottom": { "doc": "$?", "names": "$?" }, - "z": { "doc": "$?", "names": "$? z" } + "doc": "我是一个矩形,用于使@Stage具有您选择的大小的边界。", + "names": ["矩形"], + "left": { + "doc": "x轴上的舞台左边缘", + "names": "左边" + }, + "top": { + "doc": "y轴上的舞台顶部", + "names": "顶部" + }, + "right": { + "doc": "x轴上的舞台右边缘", + "names": "右边" + }, + "bottom": { + "doc": "y轴上的舞台底部", + "names": "底部" + }, + "z": { + "doc": "矩形的深度位置。", + "names": "z" + } }, "Pose": { "doc": [ @@ -2716,12 +3378,12 @@ "有好多不同的方式用这个功能制作动画。给你一个比较简单的例子:", "\\Phrase('hi' resting:Sequence({0%: Pose(rotation: 360°) 100%: Pose(rotation: 0°)})\\", "这个意思是,/开头是 0%,以 360 倾斜度开始。最后以 0 倾斜度结束/。因为我把 @Phrase 的休息姿势设成了这个,我们就会永远转圈子!", - "现在你自己试一试,用其他的@input创造一些独特的舞蹈。" + "现在你自己试一试,用其他的输入创造一些独特的舞蹈。" ], "names": ["💃", "排序"], "poses": { "doc": "一个由百分比组成的@Map介于 0% 到 100%,每个百分比都分配一个@Pose。你不用提供每个百分比,我会基于你给我的百分比无缝隙的把@Output从一个移到下一个。", - "names": "一列姿势" + "names": "姿势" }, "duration": { "doc": "我应该跳这个舞跳多长时间啊?如果要重复的跳,我不会延长时间,我只会跳的更快。", @@ -2748,67 +3410,182 @@ } }, "Velocity": { - "doc": "$?", - "names": "$? Velocity", + "doc": "我是@Stage上的一个位置。我的所有输入都是可选的,因为默认情况下我位于中心。", + "names": ["💨", "速度"], "x": { - "doc": "$?", - "names": "$? x" + "doc": "每秒在x轴上移动多少米。", + "names": "x" }, "y": { - "doc": "$?", - "names": "$? y" + "doc": "每秒在y轴上移动多少米。", + "names": "y" }, "angle": { - "doc": "$? ", - "names": "$? angle" + "doc": "每秒旋转多少度", + "names": ["角度", "°"] } }, "Matter": { - "doc": "$?", - "names": "$? Matter", - "mass": { "doc": "$?", "names": "$? mass" }, + "doc": "我是输出的物理属性,影响我与舞台上其他输出的互动。", + "names": ["⚛️", "物质"], + "mass": { "doc": "质量,以千克为单位", "names": "质量" }, "bounciness": { - "doc": "$?", - "names": "$? bounciness" + "doc": "碰撞时保留多少能量,0表示没有,1表示全部。", + "names": "弹性" }, "friction": { - "doc": "$?", - "names": "$? friction" + "doc": "保持滑动的程度;0表示没有,1表示永远。", + "names": "摩擦" }, "roundedness": { - "doc": "$?", - "names": "$? roundedness" + "doc": "圆角输出的程度;0表示没有,1表示其尺寸的100%,使尺寸成圆形。", + "names": "圆角" }, "text": { - "doc": "$?", - "names": "$? text" + "doc": "它是否可以与其他输出发生碰撞。", + "names": "文本" }, "shapes": { - "doc": "$?", - "names": "$? shapes" + "doc": "它是否可以与其他形状发生碰撞。", + "names": "地面" } }, + "Stage": { + "doc": [ + "嗨。舞台在这里。告诉我要展示什么,我会展示出来。", + "\\Stage([Phrase('stufffffff')])\\", + "如果你愿意,给我一个背景@Color,我会相应地照亮舞台。", + "\\Stage([Phrase('stufffffff')] Color(0% 0 0°) color: Color(100% 0 0°))\\", + "你也可以给我一个边框,我会进行裁剪。", + "\\Stage([Phrase('stufffffff')] Color(0% 0 0°) Rectangle(-1m -1m 1m 1m) color: Color(100% 0 0°))\\" + ], + "names": ["🎭", "舞台"], + "content": { + "doc": "要在舞台上展示的@Output列表。", + "names": "画框" + }, + "frame": { + "doc": "用于围绕舞台放置的形状和大小,隐藏其外部的一切。", + "names": "边框" + }, + "size": { + "doc": "类似于@Group/size", + "names": "大小" + }, + "face": { + "doc": "类似于@Group/face", + "names": "朝向" + }, + "place": { + "doc": "如果我是一台相机,这就是我看的地方。", + "names": "位置" + }, + "name": { + "doc": ["与@Phrase/name!相同"], + "names": "名称" + }, + "selectable": { + "doc": "与@Phrase/selectable!相同", + "names": "可选择性" + }, + "color": { + "doc": "与@Group/color相同", + "names": "颜色" + }, + "background": { + "doc": "与@Group/background相同", + "names": "背景" + }, + "opacity": { + "doc": "与@Group/opacity相同", + "names": "透明度" + }, + "offset": { + "doc": "与@Group/offset相同", + "names": "偏移" + }, + "rotation": { + "doc": "与@Group/rotation相同", + "names": ["📐", "旋转"] + }, + "scale": { + "doc": "与@Group/scale相同", + "names": "缩放" + }, + "flipx": { + "doc": "与@Group/flipx相同", + "names": "水平翻转" + }, + "flipy": { + "doc": "与@Group/flipy相同", + "names": "垂直翻转" + }, + "entering": { + "doc": "与@Group/entering相同", + "names": "进入时" + }, + "resting": { + "doc": "与@Group/resting!相同", + "names": "休息时" + }, + "moving": { + "doc": "与@Group/moving!相同", + "names": "移动时" + }, + "exiting": { + "doc": "与@Group/exiting!相同", + "names": "离开时" + }, + "duration": { + "doc": "与@Phrase/duration!相同", + "names": ["⏳", "持续时间"] + }, + "style": { + "doc": "我应该使用的动画样式。", + "names": "样式" + }, + "gravity": { + "doc": "应用于其位置在@Motion中的输出的重力。", + "names": "重力" + }, + "description": "舞台 $1[$1|] 共有 $2 个短语 $3[$3 边框|] $4" + }, "Easing": { - "straight": "$?", - "cautious": "$?", - "pokey": "$?", - "zippy": "$?" + "straight": "直线", + "cautious": "谨慎", + "pokey": "慢吞吞", + "zippy": "迅速" }, "sequence": { "sway": { - "doc": "$?", - "names": ["vaivén"], - "angle": { "doc": "$?", "names": ["ángulo"] } + "doc": "我创建一个@Sequence, 围绕@Output's的中心来回摆动。", + "names": ["摇摆"], + "angle": { + "doc": "在摇摆中倾斜的角度。", + "names": ["角度"] + } }, "bounce": { - "doc": "$?", - "names": ["rebotar"], - "height": { "doc": "$?", "names": ["altura"] } - }, - "spin": { "doc": "$?", "names": ["girar"] }, - "fadein": { "doc": "$?", "names": ["revelar"] }, - "popup": { "doc": "$?", "names": ["surgir"] }, - "shake": { "doc": "$?", "names": ["agitar"] } + "doc": "我创建一个@Sequence, 使@Output以指定的高度弹跳。", + "names": ["弹跳"], + "height": { "doc": "弹跳的高度。", "names": ["高度"] } + }, + "spin": { + "doc": "我创建一个@Sequence, 使@Output围绕其中心旋转。", + "names": ["旋转"] + }, + "fadein": { + "doc": "我创建一个@Sequence, 将@Output从不可见状态淡入可见状态。", + "names": ["淡入"] + }, + "popup": { + "doc": "我创建一个@Sequence, 使@Output迅速放大然后缩小到正常尺寸。", + "names": ["弹出"] + }, + "shake": { + "doc": "我创建一个@Sequence, 使@Output看起来像是害怕的。", + "names": ["抖动"] + } } }, "ui": { @@ -2829,7 +3606,7 @@ "loading": { "message": "正在加载字体和文本,请稍候!" }, - "back": "返回上一页" + "home": "去首页" }, "tile": { "toggle": { @@ -2842,6 +3619,12 @@ "off": "显示此瓷砖" } }, + "label": { + "output": "舞台", + "palette": "调色板", + "docs": "指南", + "source": "源文件" + }, "button": { "collapse": "折叠窗口" } @@ -2983,9 +3766,12 @@ "insertConvert": "插入转换符号", "insertPrevious": "插入前一个符号", "insertTable": "插入表符号", + "insertTableClose": "插入表格关闭符号", + "insertBorrow": "插入借阅", + "insertShare": "插入分享", "insertLine": "插入换行符", "backspace": "删除选择或前一个字符", - "delete": "$?", + "delete": "删除", "cut": "剪切选择", "copy": "复制选择", "paste": "粘贴键盘内容", @@ -2994,7 +3780,8 @@ "type": "键入字符", "undo": "类型字符", "redo": "撤销上次编辑", - "search": "查找要插入的特殊字符" + "search": "查找要插入的特殊字符", + "tidy": "整理间距" } }, "conflicts": { @@ -3142,10 +3929,12 @@ "subheader": { "selected": "选择", "supported": "可用的", + "coming": "$", "help": "帮我们翻译 。。。" }, "button": { "show": "切换语言", + "replace": "$", "add": "添加语言", "remove": "删除语言" } @@ -3223,7 +4012,11 @@ "message": "这是什么地方?我们能回家吗?" }, "landing": { - "call": ["$?"], + "call": ["嗨!想要与我们一起赋予文字生命吗?😊"], + "beta": [ + "Wordplay 处于 测试阶段。这意味着功能可能会更改或无法按预期工作,并且本地化可能不完整。", + "但这也意味着我们需要您的反馈!请在 上报告错误并分享想法。如果您能帮助,请查看我们的 <1.0 计划@https://github.com/wordplaydev/wordplay/milestones/1.0> 和 <贡献信息@https://github.com/wordplaydev/wordplay/wiki/contribute>。" + ], "link": { "about": "这个地方为什么存在?", "learn": "这是什么地方?", @@ -3243,24 +4036,31 @@ "projects": { "header": "项目", "projectprompt": "准备好说些什么了吗?您可以开始创建一个新项目,或者继续在现有项目上工作。如果您遇到困难,继续学习 ", - "galleriesheader": "画廊", + "archiveheader": "已归档", + "archiveprompt": "这些是您已归档的项目。只有所有者才能永久删除或取消归档它们。归档的项目将在最后编辑后的30天内永久删除。", "galleriesheader": "画廊", "galleryprompt": "创建和策划画廊,与他人分享项目集合", "button": { "newproject": "新项目", "editproject": "编辑这个项目", - "newgallery": "新画廊" + "newgallery": "新画廊", + "unarchive": "取消归档此项目" }, "confirm": { "archive": { "description": "存档这个表演", "prompt": "存档" + }, + "delete": { + "description": "永久删除这个表演", + "prompt": "永久删除" } }, "error": { "noaccess": "无法连接网络。", - "loggedout": "您必须登录才能创建和更改画廊。", - "newgallery": "我们无法创建新的画廊。" - } + "nogalleryedits": "您必须登录才能创建和修改画廊。", + "newgallery": "我们无法创建新的画廊。", + "nodeletes": "您必须登录才能删除已归档的项目。", + "delete": "哎呀,我们无法删除该项目!" } }, "galleries": { "header": "画廊", @@ -3282,11 +4082,30 @@ }, "login": { "header": "登录", + "subheader": { + "email": "电子邮件链接", + "username": "用户名 + 密码" + }, "anonymous": "匿名", "prompt": { "login": "您的表演保存在本设备上,而不是在线。要将它们保存在线,请提交您的电子邮件以获取登录链接。", + "age": { + "label": "你多大了?", + "modes": ["12岁或以下", "13岁或以上"] + }, "enter": "看起来您的登录链接来自不同的浏览器或设备。您可以再次输入您的电子邮件地址,以确保是您吗?", "play": "您已登录,现在我们可以将您的项目保存在线上!想要创建点什么吗?", + "emailrules": [ + "• 如果你*12岁或以下*,请不要提供你的电子邮件地址。", + "• 如果你*无法访问*你的电子邮件账户,你将无法登录或更新你的电子邮件地址。" + ], + "tooyoung": "您必须年满13岁或以上才能使用电子邮件登录。", + "usernamerules": [ + "• *用户名*不应包含可识别的信息(例如姓名),不能是电子邮件地址,并且至少应为5个字符长。", + "• *密码*必须至少为10个字符长;如果你没有使用密码管理器,请选择三个你会记住的长单词。", + "• *如果你忘记了密码*,你将无法恢复你的账户,因为我们没有其他方法知道这是你。请将你的密码安全地存放在一个地方,比如密码管理器。" + ], + "passwordreminder": "看起来你正在创建一个账户。请检查你的密码,确保它被安全地保存并输入正确,然后重新提交以创建你的账户。", "change": "想要更改您的电子邮件地址吗?提交新的电子邮件地址,我们将向旧的地址发送确认信息。", "sent": "请检查您的电子邮件以获取登录链接。", "logout": "离开共享设备,想要保持项目的私密性吗?注销,我们将从该设备中删除您的项目。它们仍将在线存储。", @@ -3303,7 +4122,8 @@ "failure": "无法登录 :(", "offline": "您似乎处于离线状态。", "unchanged": "我们无法更改您的电子邮件地址,但我们不知道原因。", - "delete": "我们无法删除您的帐户,但我们不知道原因。" + "delete": "我们无法删除您的帐户,但我们不知道原因。", + "wrongPassword": "无效的用户名和密码。可能是密码错误,或者其他人已经使用了这个用户名。" }, "feedback": { "changing": "正在提交新的电子邮件地址...", @@ -3313,6 +4133,14 @@ "email": { "description": "编辑登录邮件", "placeholder": "邮件" + }, + "username": { + "description": "登录用户名,请勿使用可识别个人身份的信息", + "placeholder": "用户名" + }, + "password": { + "description": "登录密码,至少10个字符", + "placeholder": "密码" } }, "button": { @@ -3359,14 +4187,29 @@ "consequences": [ "如果我们发现一个项目或画廊违反了这些规定,我们将把它标记为私有,并阻止他们将来发布任何公开项目。您可以通过举报任何您认为违反规定的内容来帮助我们执行这些规定。" ] + }, + "donate": { + "header": "$", + "prompt": "Enable more accessible, global programming", + "content": [ + "Wordplay is a free, community-based project supported by the . We rely on gifts from people who believe in our mission of accessible, language-inclusive, educational programming languages.", + "Here are our current costs:", + "• We compensate University of Washington undergraduates, especially those who are disabled or whose first language was not English, to evolve and maintain the project. This is about 90% of our costs.", + "• We give stipends to teachers who we collaborate with to develop multilingual, accessible curricula.", + "• We pay Google for bandwidth and storage, and services.", + "• We pay annually for the domain.", + "Our current costs, assuming 5 undergraduates at $$20 USD//hour, 10 hours//week during the academic year (36 weeks) and 2 undergraduates during the summer (12 weeks), plus cloud services, are about $$60K USD per year.", + "If 2,400 people gave $$25 USD per year, that would cover our current costs, with any excess going to compensation more students and teachers.", + "Can you be one of those 2,400 people? If so, here's our University of Washington giving link:" + ] } }, "edit": { "node": "$1$2[, 类型 $2|]", - "before": "$?", - "inside": "$?", - "between": "$?", - "line": "$?", + "before": "在 $1[$1|end] 之前", + "inside": "在 $1 内", + "between": "在 $1 和 $2 之间", + "line": "$1[$1|start] 和 $2[$2|end]之间的空行", "conflicts": "$1 冲突", "assign": "/$2[急于插入|考虑离开].../", "append": "/急于插入。。。/", @@ -3381,8 +4224,60 @@ "unparsable": "无法解析的模板: $1" } }, - "rules": { - "violence": "不得发表煽动、鼓励或庆祝暴力、伤害或自残的言论。", - "dehumanization": "不得以种族、族裔、国籍、种姓、性取向、性别、宗教、年龄、能力或外貌为基础,对个人或群体进行非人化的言辞。" - } + "moderation": { + "warning": { + "header": "警告", + "explanation": "一位版主认为这个内容可能:" + }, + "blocked": { + "header": "已封锁", + "explanation": "一位版主认为这个内容可能:" + }, + "unmoderated": { + "header": "注意", + "explanation": "此内容尚未经过审核。可能:" + }, + "moderate": { + "header": "审查", + "explanation": "请审查此项目,判断其是否包含以下内容。如果包含,内容将受到警告或封锁。如果不确定,您可以跳过。" + }, + "flags": { + "violence": "煽动、鼓励或庆祝对任何人的暴力、伤害或自残行为。", + "dehumanization": "基于种族、民族、国籍、种姓、性取向、性别、宗教、年龄、能力或外貌对个人或群体进行非人格化描述。", + "disclosure": "披露其他人的私人信息,如姓名、联系方式或实际地址。", + "misinformation": "包含虚假、误导性、欺骗性或操纵性信息。" + }, + "button": { + "submit": { + "tip": "保存这些审查设置", + "label": "保存" + }, + "skip": { + "tip": "跳过此项目", + "label": "跳过" + } + } + }, + "gallery": { + "games": { + "name": "游戏", + "description": "交互式文字和符号游戏。" + }, + "visualizations": { + "name": "可视化", + "description": "文字的可视化展示。" + }, + "motion": { + "name": "运动", + "description": "运动和碰撞的示例。" + }, + "av": { + "name": "音频/视频", + "description": "使用音量、音调和视频作为输入。" + }, + "tools": { + "name": "工具", + "description": "简单的实用工具和应用程序。" + } + } }