Functional Programming

Functional Programming

Functional Programming

Dec 3, 2018

Building Terminal User Interfaces in Haskell

Building Terminal User Interfaces in Haskell

Building Terminal User Interfaces in Haskell

Our webinars are continuing to be as popular as ever and

Tom Sydney Kerckhove's (Tech Lead at FP Complete) webinar on

"Building Terminal User Interfaces with Haskell" was no exception.

We had 426 people registered for the event which aired on

Wednesday, November 28th at 10:00 am PST. If you tuned in live you

would have seen Tom Sydney Kerckhove programming at lightning

speeds. We are so glad we recorded the event because you need to be

able to stop and start the video at your own pace to keep up with

the action. IMPORTANT NOTE: Before you watch the video you may want to

check out the Free Training offer we are making available to the

first 20 people who register. You can find out more below or by

clicking here to register now

.

About the Webinar

In this month's webinar, Tom Sydney Kerckhove will

demonstrate just how easy it is to get started with Terminal User

Interfaces (TUIs).  As a recap, TUIs are text-based user

interfaces for use from a terminal. They are usually lightweight,

and most importantly, in this webinar, you will learn how easy they

are to use. You will also learn how to get up and running by making

your own TUI applications with live-coding example TUIs with the

Brick library.


Topics to be covered:

  • The Brick architecture

  • Basic cursors

  • Simple example TUI applications

Watch the Webinar


We decided to include the chat log for this webinar, and it can

be seen at the end of this blog post. For those of you that want

more information the TUI Syd built check out the following

links:

A base to start a TUI from:  https://github.com/NorfairKing/tui-base

A semantic tree-based editor to replace Emacs Org Mode for

GTD: https://github.com/NorfairKing/smos

A declarative terminal UI programming library written in

Haskell: https://github.com/jtdaugherty/brick

At FP Complete, we do so many things to help companies it's hard to

encapsulate our impact in a few words.  They say a picture is

worth a thousand words, so a video has to be worth 10,000 words (at

least). Therefore, to tell all we can in as little time as

possible, we recently produced a new explainer video. Check it out

by clicking the video link below. It's only 108 seconds to get the

full story of FP Complete. One last thing. We have a home page a

facelift, and you can check it out here.

Check out our new Explainer Video


We want your feedback for webinar topics

We would like to hear your suggestions for future webinar

topics. The simplest way to accomplish this is to add a

comment to this blog post with your suggestion. Alternatively, send

your suggestion via email to socialmedia@fpcomplete.com.

Webinar Chat Log

We find it useful to share what was chatted about during the

webinar. You can see the chat flow below.

10:00:38 From oren rozen : Hi

10:00:48 From Michael Snoyman : Welcome everyone

10:00:51 From Alexandre Garcia de Oliveira : Hi

10:00:57 From Nick Linker to All panelists : Hi!

10:01:00 From Andre Artus to All panelists : hi

10:01:21 From oren rozen : my first webinar so guide me if I need

to do something special

10:01:22 From Andrey Prokopenko : Hi everybody!

10:01:34 From Tristian Azuara : Hello!

10:01:37 From Frank Stüss to All panelists : hi everyone!

10:01:40 From Artem Chernyak : Hi!

10:01:40 From bogdan : Hi!

10:01:41 From Dan Banta : Hello. :)

10:01:44 From furnost to All panelists : Hello

10:01:45 From Joerg W to All panelists : Hi!

10:01:46 From Alexei Pastuchov to All panelists : Hi

10:02:09 From Frank Stüss to All panelists : thanks for doing

this!

10:02:19 From Pedro Furlanetto : Hello

10:02:32 From furnost to All panelists : Hi all!

10:02:33 From Andrew Starodubtsev to All panelists : hello!

10:02:40 From Daniel Leones to All panelists : Hello.

10:03:06 From Michael Snoyman : Feel free to ask questions here,

I'll try to either respond or pass them along :)

10:03:50 From Pedro Furlanetto : Curses?

10:03:58 From Pedro Furlanetto : * Library I mean

10:04:12 From Michael Snoyman : I'm not sure what the question is,

sorry

10:04:29 From R Primus : Is it using the nurses library?

10:04:45 From Michael Snoyman : Under the surface, yes, though

we'll get into the libraries

10:04:51 From Pedro Furlanetto : curses and lcurses library for

Unix terminal UIs

10:04:52 From Michael Snoyman :

https://github.com/NorfairKing/tui-base

10:05:03 From oren rozen : Is it possible to run it with nix?

10:05:21 From Michael Snoyman : I believe so, though I haven't

tested it myself in this case

10:05:46 From Tristian Azuara : Hi I might have to leave the

webinar; for a work call; will the recording be available

somewhere?

10:05:54 From Niklas Hambuechen to All panelists : It uses vty , a

competitor to ncurses : https://hackage.haskell.org/package/vty

10:06:16 From Michael Snoyman : Yes, we'll make the recording

available when ready (probably in the next few days)

10:06:19 From Niklas Hambuechen to All panelists : See the

dependencies of https://hackage.haskell.org/package/brick

10:06:35 From Michael Snoyman : And announce on our blog and

Twitter account

10:06:41 From Michael Snoyman : Niklas: thanks for the

correction

10:06:43 From Tristian Azuara : Awesome!!, thank you; I’ll stay for

as long as possible.

10:06:59 From furnost to All panelists : Awesome, thanks for the

recording!

10:07:56 From Alexandre Garcia de Oliveira : Widget is a dependent

type?

10:07:59 From Alexandre Garcia de Oliveira : is

10:08:19 From Corey O'Connor to All panelists : ( a R Primus to be

clear - The " ncurses " UI widgets are not used. ncurses is only

used for loading termcap data. )

10:08:46 From Alexandre Garcia de Oliveira : Ok. Thank you

10:08:58 From Michael Snoyman : +1

10:09:08 From Michael Snoyman :

https://www.stackage.org/haddock/lts-12.20/brick-0.37.2/Brick-Types.html#t:Widget

10:09:12 From Pedro Furlanetto : Are the slides a brick app?

10:09:30 From Robert Pearce : ^ +1

10:09:33 From Konstantin Yegorov to All panelists :

C:HaskellTUI_webinartui-base>stack install

Downloaded lts -12.18 build plan.

AesonException "Error in $.packages.cassava.constraints.flags:

failed to parse field packages: failed to parse field constraints:

failed to parse f

ield flags: Invalid flag name: "bytestring--lt-0_10_4""

10:09:42 From Michael Snoyman : You need to upgrade Stack, try

`stack upgrade`

10:09:50 From Konstantin Yegorov to All panelists : 10x

10:10:10 From Michael Snoyman : I'll save the slides question to

the end

10:10:41 From Niklas Hambüchen to All panelists : oren rozen: The

example is a simple Haskell package, so like all other packages, it

work with nix as well.

10:11:24 From Niklas Hambüchen to All panelists : *works

10:11:33 From Alexandre Garcia de Oliveira : Nope

10:11:40 From furnost to All panelists : Fine by me

10:11:41 From oren rozen : Go ahead

10:11:52 From Nick Linker to All panelists : clear

10:15:43 From Andrey Prokopenko : please move on

10:15:47 From Pedro Furlanetto : can you please, write the type

vBox in a comment in the source

10:15:50 From Nick Linker : its ok

10:16:13 From Andre Artus : I'm battling to watch and follow along

at the same time.

10:16:17 From Michael Snoyman :

https://www.stackage.org/haddock/lts-12.20/brick-0.37.2/Brick-Widgets-Core.html#v:vBox

10:16:51 From Michael Snoyman : Andre: if you're having trouble,

keep in mind that the video will also be recorded if you'd like to

try going through it with a pause button later

10:17:34 From Andre Artus : Thanks, Michael, I will just watch it

now and follow through it later.

10:18:12 From Pedro Furlanetto : Cursor == Zipper?

10:18:18 From Michael Snoyman : Yes

10:18:21 From Alexandre Garcia de Oliveira : Yes

10:18:28 From Pedro Furlanetto : thx

10:18:49 From Nick Linker : Why do we need nonEmptySelectNext/Prev

functions and not just fields of NonEmptyCursor data type?

10:19:37 From Michael Snoyman : We would need to tie the knot in a

funny way to make that happen. If you try to implement such a

field-based approach, you'll see the problem

10:20:59 From Nick Linker : Hm, ok.

10:22:39 From Nick Linker : What the signature of `continue`

function?

10:22:46 From Michael Snoyman : One sec

10:22:56 From Nick Linker : a -> EventM a?

10:23:08 From Michael Snoyman : Almost

https://www.stackage.org/haddock/lts-12.20/brick-0.37.2/Brick-Main.html#v:continue

10:23:14 From Michael Snoyman : continue :: s -> EventM n (Next

s)

10:23:15 From Nick Linker : Thanks!

10:23:23 From Nick Linker : I see.

10:23:38 From Michael Snoyman : In case anyone's curious, I'm using

the Stackage search on this page:

https://www.stackage.org/lts-12.20/hoogle?q=continue&package=brick

10:23:51 From Nick Linker : Thanks, Michael.

10:25:53 From Corey O'Connor to All panelists : true that @ boolean

blindness ;)

10:26:17 From furnost to All panelists : everything clear

10:26:19 From Andre Artus : good so far

10:26:50 From Michael Snoyman : wehavetogodeeper.gif

10:27:01 From Nick Linker : haha

10:29:54 From Alexandre Garcia de Oliveira : Go ahead

10:30:00 From Nick Linker : cool, no question so far

10:30:39 From Pedro Furlanetto : That’s cool

10:30:49 From Niklas Hambüchen : I can't see vty or patat in the

deps of patat

10:30:58 From Niklas Hambüchen : sorry "vty or brick"

10:31:18 From Pedro Furlanetto : Let’s dive deeper

10:31:40 From Daniel Leones to All panelists : I think you're using

vim. Does Haskell autocompletion is included?

10:31:49 From Robert Pearce : Thanks! gotta bounce. looking forward

to the video. This is great <3

10:32:32 From Corey O'Connor to All panelists : (probably a vty bug

XD)

10:32:35 From Andrey Prokopenko : cool

10:32:35 From Alexandre Garcia de Oliveira : This is cooler than

doing front-end

10:32:39 From bogdan : Hi, can you make a small overview of

brick

10:32:42 From bogdan : ?

10:32:47 From Bulent Basaran : How easy would it be to draw

dir/files differently?

10:32:52 From Karol Kopiec to All panelists : thx really cool

10:34:08 From Corey O'Connor to All panelists : I would akin brick

to a UI toolkit. Like GTK or QT.

10:34:15 From Peter Young : Thanks for presentation. Very cool!

10:34:18 From bogdan : Ok, thank you)

10:34:21 From oren rozen : thank you

10:34:24 From oren rozen : :)

10:34:30 From Andre Artus : Are there higher level UI elements?

I.e. composing a from without having to construct everything?

10:34:39 From furnost to All panelists : thanks! amazed at the dev

speed

10:34:46 From Daniel Leones to All panelists : Thanks for the

presentation.

10:34:59 From Bulent Basaran : in emacs/shell mode: I am getting an

error: tui: user error (Terminal does not define required

capability "cup")

10:35:17 From Corey O'Connor to All panelists : "composing a form"?

As in, handling the user interaction and data submission?

10:35:30 From Michael Snoyman : I don't think we'll be able to

debug the emacs shell mode support, sorry

10:35:48 From Bulent Basaran : no problem :-)

10:36:08 From Mo Kweon : will the code be available after this?

10:36:38 From Daniel Leones to All panelists : This:

https://github.com/NorfairKing/tui-base

10:36:42 From Pedro Furlanetto : Update the attributes map

10:37:11 From Michael Snoyman : Good call Pedro :)

10:37:18 From Michael Snoyman : I was about to mention it

10:37:23 From Michael Snoyman : But Syd got there first

10:38:02 From oren rozen : Both the selection is red and the file

are red

10:38:42 From Pedro Furlanetto : making selected the last?

10:38:45 From Marc Paterno : I am accustomed to using test-driven

development,. What Haskell tool or library would you suggest for

doing that?

10:38:45 From Iurii Lukaniuk to All panelists : Can we send events

to Brick app from another thread?

For example, events about changes of directory contents

10:38:49 From Pedro Furlanetto : (pure guessing)

10:39:08 From Alexandre Garcia de Oliveira : nice

10:39:10 From bogdan : Question is of topic: what extensions are

used for vim? or neovim ? (you can not answer for this

question)

10:39:12 From Corey O'Connor to All panelists : cool!

10:39:13 From Frank Stüss to All panelists : (y)

10:39:13 From Pedro Furlanetto : yep

10:39:13 From SORIN STOICESCU to All panelists : Hi, could you

share some thoughts about structuring Brick as an interface to

something multithreaded/async? like, imagine you select a file &

the program uploads it somewhere, in the background, showing some

progress bar for it

10:39:16 From Bulent Basaran : beautiful!

10:39:49 From bogdan : * is out of topic

10:39:52 From Andre Artus : Cool

10:40:28 From Artem Chernyak : Brick reminds me a lot of the Redux

architecture

10:40:35 From Artem Chernyak : From JS

10:41:53 From Pedro Furlanetto : is the draw always of the entire

screen or is it able to update only certain portions?

10:41:53 From Nick Linker : Or ELM, but with some additional type

params

10:42:01 From Pedro Furlanetto : *screen ~= terminal

10:42:08 From bogdan : Can I have like deadlocks with channels?

10:42:23 From Mo Kweon : Where is the code available?

10:42:39 From Pedro Furlanetto : The link is in the beginning of

the chat

10:42:41 From Michael Snoyman : We'll send out an email with code

and video links

10:42:48 From Daniel Leones to All panelists : Nice.

10:43:13 From Marc Paterno : I am accustomed to using test-driven

development ,. What Haskell tool or library would you suggest for

doing that?

10:43:16 From bogdan : Thanks for answering)

10:43:27 From Nick Linker : Let me some more side questions:

Could you describe your workspace environment. I guess this is zsh

with oh-my- zsh installed, but is there something beyound this?

How do you make immediate stack build on save?

How do you make fast reformatting of the last entered piece of

code?

How do you configured type hints?

Thanks

10:43:29 From Jon Schoning to All panelists : Do you ever embed a

brick App into a higher level component in your application? or

just use the App directly?

10:43:53 From Jon Schoning to All panelists : i.e. Brick does not

seem like a Monad Transformer itself

10:44:22 From Marc Paterno : Thanks

10:45:41 From Pedro Furlanetto : xmonad is going on, no?

10:46:02 From Karl Berger to All panelists : There was a good

webinar previously on Haskell workflow, would recommend!

10:46:06 From Mo Kweon : looks like it

10:46:44 From Nick Linker : Thank you for the answers!

10:46:46 From Mo Kweon : yeah

10:46:48 From oren rozen : this is a tooling question as well: just

wonder did you guys have tried haskell -ide-engine

10:47:07 From oren rozen : Ok thanks

10:47:08 From furnost to All panelists : +1 for webinar idea

10:47:12 From Artem Chernyak : Thank you so much this was a great

demo and walkthrough!

10:47:15 From bogdan : Wonderful presentation)

10:47:16 From LUC DUZAN to All panelists : What is the biggest TUI

you have written so far ?

10:47:17 From Mo Kweon : Thank you

10:47:18 From furnost to All panelists : thanks !

10:47:19 From Frank Stüss to All panelists : super! thank you

10:47:21 From Andre Artus : Thanks, very informative

10:47:23 From Daniel Leones to All panelists : Thank you

10:47:24 From Michael Irving : Thank you

10:47:26 From SORIN STOICESCU to All panelists : Thank you

10:47:28 From Karl Berger to All panelists : Thanks everyone

10:47:29 From Pedro Furlanetto : Thanks a lot Tom and Michael

10:47:36 From Niklas Hambüchen to All panelists : I have tried HIE

a couple times, getting better, but still way to go, also depending

on the editor you use

10:47:39 From Dan Banta : Fantastic. Thank you.

10:47:41 From Carlos Gomez : thx

10:47:43 From Marcel Tilly to All panelists : Thx

10:47:44 From Inga Shchelik to All panelists : thank you!

10:47:45 From Alexandre Garcia de Oliveira : Thank you

10:47:45 From Karol Kopiec to All panelists : thank you

10:47:45 From Nick Linker : Awesome

10:47:46 From Andre Artus : Bye.

10:47:46 From Franck Rasolo : Thanks for the presentation, looking

forward to the links!

10:47:47 From Frank Stüss to All panelists : bye all

10:47:47 From LUC DUZAN to All panelists : Thank you a lot!

10:47:48 From Corey O'Connor to All panelists : Thanks!

10:47:48 From Andrey Prokopenko : Thanks!

10:47:48 From Pedro Furlanetto : You too

10:47:50 From Konstantin Yegorov to All panelists : Thanks

everyone

10:47:53 From Marcel Tilly to All panelists : great

presentation

10:47:55 From Mo Kweon : What is a next presentation in the

plan?