SkillAgentSearch skills...

FuncSug

FuncSug is a simple alternative to event-driven programming and game loops. No main loops or event-action associations any more thanks to concurrency, waiting for specific events and a special handling of interruptions.

Install / Use

/learn @cl4cnam/FuncSug

README

<img height="50" alt="Funcy_logo" src="https://github.com/user-attachments/assets/b9ad10d5-65f3-460f-b660-a8e265a13db8" /> FuncSug – A language to express concurrent and sequential behaviors structuredly

<p align="center"> <img src="https://github.com/user-attachments/assets/1b64ac3e-6701-4427-9670-5b34659819c0" alt="When a branch is finished the other branch is definitively interrupted" width="450"> <br> <em>When a branch is finished the other branch is definitively interrupted</em> <br> <br> <img src="https://github.com/user-attachments/assets/c5ab6dd8-143b-4aaf-a5ef-1bf0514f30be" alt="code" width="450"> </p>

header

<br> <br>

▶️🚀Try it in the Playground

<p align="center"> <a href="https://cl4cnam.github.io/try_FuncSug/?example=drinkingCow"> <img width="380" height="201" alt="logoCawPG" src="https://github.com/user-attachments/assets/474f001b-35e8-4e16-84d4-e0b29e2d9aa2" /></a> </p>

<br> <br>

🔄No mandatory main loop any more

FuncSug is an experimental dynamic language that aims to simplify GUI programming in browser, as a complement to JavaScript. The convenience is that FuncSug doesn't force you to structure your code according to an event loop or a game loop.

To grasp the specificity of FuncSug, the easiest way is to visit the 🕹️playground.

👉 🧪Online Playground with complete examples (including 🕹️mini-games) 👈

🎓Tutorials - 🌱Getting started - 🧩Examples - 🧵REPL
<br> <br>

🎯The main goal of FuncSug might be painted as follows:

<img width="843" height="547" alt="noSlice" src="https://github.com/user-attachments/assets/64ef968a-6bbb-432d-92cb-67f69696dd58" />

FuncSug enables a more linear code in line with async/await and structured concurrency. It replaces event-driven code structures with easy-to-use seemingly parallel syntaxes (without using OS threads). It allows you to program like the event loop doesn't exist (Not replaced by a game loop either).

🧩 A few samples

🎶 🎶 Play multiple sounds at the same time

parallel ||
	playSoundFile('sound1.mp3')
||
	playSoundFile('sound2.mp3')
||
	playSoundFile('sound3.mp3')

Try it in the Playground

🎶 🔁 Play multiple sounds one at a time

playSoundFile('sound1.mp3')
playSoundFile('sound2.mp3')
playSoundFile('sound3.mp3')

Try it in the Playground

⏱️Timeouts

displayNewMessage('What is ...?')
parallel exitAfter 1 finished ||
	var theAnswer := awaitHumanText()
||
	waitSeconds(15)

🔘A simple choice

displayNewMessage('<button id="A">I choose A</button> <button id="B">I choose B</button>')

parallel(select 1) ||
||=================
	awaitClickBeep('#A')
...---
	displayNewMessage("You've chosen A")
||================
	awaitClickBeep('#B')
...---
	displayNewMessage("You've chosen B")

Try it in the Playground

🔧A less simple choice

displayNewMessage(`
	<button id="A">I choose A</button>
	<button id="B">I choose B</button>
`)

parallel(select 1) ||
||=================
	awaitClickBeep('#A')
	displayNewMessage('<button id="Aconfirmed">Yes, I choose A</button>')
	awaitClickBeep('#Aconfirmed')
...---
	displayNewMessage("You've chosen A")
||================
	awaitClickBeep('#B')
...---
	displayNewMessage("You've chosen B")
||================
	waitSeconds(5)
...---
	displayNewMessage("You've hesitated")

Try it in the Playground

🤔 Why

Many people ask why GUI programming is so difficult. Some of common difficulties come from event-driven programming problems. That's why, with FuncSug, programmers do NOT have to follow the event-driven programming paradigm. For example, you no longer link an event to an action (like "addEventListener" does) and so no longer have the corresponding problems.

⚙️How

FuncSug suppresses event-driven programming problems: callback hell and state management.

Advantages:

  • It avoids callback hell (You don't need callback any more).
  • Your code follows the order of execution so you avoid spaghetti code and debug more easily.
  • It solves the state management problem (It eliminates the need to manage all the combinations of component states).
  • It easily manages task cancellations (including task timeouts).
  • It can detect a change in the value of a variable and react accordingly.
  • It's deterministic.
  • (You can also include JavaScript snippets, pass FuncSug variables to it and get back JavaScript return).

⚙️by means of:

  • explicit logical parallelism,
  • block cancellations,
  • and "await event" instructions.

Please, let me know what you think (Github discussions, Mastodon).<br> I'd be happy to read your opinion and answer your questions.

solve2_c2

↔️Compare

These two codes do the same thing (on mobile, please scroll right to see the FuncSug code):

<table> <tr> <th align="center">JavaScript/DOM</th> <th align="center">FuncSug</th> </tr> <tr> <td>
let numberOfClick
function $(id) {
   return document.getElementById(id)
}
function launch() {
   $('launch').removeEventListener('click', launch)
   setTimeout(
      ()=>{
         $('clickZone')
         .removeEventListener('click', clickZone)
         console.log("Good job! See you soon!")
      },
      30000
   )
   numberOfClick = 0
   $('clickZone')
   .addEventListener('click', clickZone)
}
let timeoutID
function clickZone() {
   if (numberOfClick == 0) {
      timeoutID = setTimeout(
         ()=>{
            if (numberOfClick < 3) {
               numberOfClick = 0
               console.log("Non-triple click")
            }
         },
         2000
      )
   }
   numberOfClick += 1
   if (numberOfClick == 3) {
      numberOfClick = 0
      console.log("Triple click")
      clearTimeout(timeoutID)
   }
}
$('launch').addEventListener('click', launch)
</td> <td>
awaitClickBeep('#launch')
parallel exitAfter 1 finished ||
   waitSeconds(30)
||
   while true:
      awaitClickBeep('#clickZone')
      parallel exitAfter 1 finished ||
         awaitClickBeep('#clickZone')
         awaitClickBeep('#clickZone')
         print("Triple click")
      ||
         waitSeconds(2)
         print("Non-triple click")
print("Good job! See you soon!")
</td> </tr> </table>

If you copy and paste, replace each three initial spaces by one tabulation (Github markdown doesn't allow to change tabulation size in this context).

👀Get a taste of the language

Have a look at:

<!-- C'est un commentaire à ne pas retirer de suite au cas où <p align="center"> <a href="https://github.com/cl4cnam/Memory/blob/main/memory.fg"> <img <img src="https://github.com/user-attachments/assets/90df278a-527b-4d49-b283-bb0e7957ca7f" width="60" alt="Memory"><br> <sub>trio Memory game</sub> </a> <a href="URL_2"> <img src="IMG_2" width="60" alt="Hypertext fiction"><br> <sub>Hypertext fiction</sub> </a> <a href="URL_3"> <img src="IMG_3" width="60" alt="Guess the number"><br> <sub>Guess the number</sub> </a> </p> -->

Look at the global structure of the code: One cannot follow this structure in usual programming language.

Let's take, for example, the 'Make Gems' code:

In this language, there is no need to build a ball object, just call a function lifeOfBall. You just run multiple lifeOfBall, birthOfGem and a lifeOfPaddle in parallel. These functions do not build objects: they are just like any classical function. <br> In the body of lifeOfPaddle, just code the various behaviors of the ball in parallel.

In 'Guess the Number', gameCourse is just a function. The line just after the call of gameCourse is executed only when the player has found the number, that is

Related Skills

View on GitHub
GitHub Stars14
CategoryProduct
Updated1mo ago
Forks0

Languages

JavaScript

Security Score

95/100

Audited on Feb 23, 2026

No findings