Programming thread

the language itself is enjoyable, has built in support for many things, etc. way easier to write in than apl or bqn, as its stack based
ok they made a stack based apl HOW THE FUCK IS THAT A FUNCTIONAL LANGUAGE
yeah, recently he added an option to turn it off
yeah and it has a crying face emoji
it was made by a they/them in rust
nigger nigger nigger nigger nigger
what a niggy nigger

you should try a REAL LANGUAGE like lisp or haskell or fucking anything, hell i respect perl as a functional language more than this garbage
 
What are the best, free resources to start learning how to code?
we get one of you every 2 weeks so there's a thread about it but i actually can't find it in search so i will tell you:
  1. there are programming tutorials littering the internet with such unfathomable density that you can't walk 3 steps without fucking tripping on one
  2. pick a random one of them
  3. have a go on it and actually write programs (you will not learn anything watching 500 youtube tutorials with a blank stare)
one day you will want to get in on the holy wars and viciously shit on programming languages you don't like, but since you are still a layman you should just install python and try to make some garbage text adventure like half of us here did
 
you should just install python and try to make some garbage text adventure like half of us here did
I learned to code in QBASIC, using the built in documentation, after finding a BASIC program in a book once. Not a technique that'd resonate with the youth, but still a testament to the quality of documentation, even as early as '93.

One of my first attempted projects: garbage text adventure.
 
ok they made a stack based apl HOW THE FUCK IS THAT A FUNCTIONAL LANGUAGE
yeah my bad i confused it with array languages, thats on me, sorry
nigger nigger nigger nigger nigger
what a niggy nigger
hes a chink actually......
you should try a REAL LANGUAGE like lisp or haskell or fucking anything,
yeah ive tried using haskell once for advent of code, it was fun, but it did feel like i was doing something wrong
 
One of my first attempted projects: garbage text adventure.
garbage text adventures make for good first projects now that i think about it since you have to learn how to structure things a bit or you instantly get yandev'd
yeah my bad i confused it with array languages, thats on me, sorry
jesus christ :cryblood:
hes a chink actually......
nigger (yellow)
yeah ive tried using haskell once for advent of code, it was fun, but it did feel like i was doing something wrong
haskell is not meant to be used by humans, you probably tried using it as a human
 
haskell is not meant to be used by humans, you probably tried using it as a human
im-only-human-im-only-human-after-all.gif
 
I once again wish to shill the Common Lisp–Haskell hybrid language Coalton (that embeds on top of CL), the developer of which has given a talk at the recent European Lisp Symposium on using Coalton's power in the industry:
I implore you to give it a try!

Edit: One major boon of Coalton that I kept thinking back to while building a decently sized Haskell project from scratch the past month is that Haskell does not have metaprogramming or macros in any real sense. Template Haskell does not generate real GHC AST; by contrast you get that for free in Coalton with a great amount of flexibility for sharing type information between Coalton and the underlying dynamic Common Lisp. I really hope this goes places because "LISP's metaprogramming + Haskell's lazyness and strong static type system (preferably with optional dependent types)" is pretty much my conception of a perfect language
 
Last edited:
I once again wish to shill the Common Lisp–Haskell hybrid language Coalton (that embeds on top of CL), the developer of which has given a talk at the recent European Lisp Symposium on using Coalton's power in the industry:
oh yeah, I've heard about it, appeared on my github a few times, ive never tried it tho, since i havent really tried common lisp yet
 
  • Like
Reactions: Belisarius Cawl
Since we are on the topic of functional languages. Graham Hutton each year publishes his Haskell lectures on his YouTube channel.
They are reasonably easy to follow. Afterwards for those who are interested in further learning Bartosz Milewski channel has lectures on Category Theory.
dont start programming with haskell that probably just leads to a path of frustration
 
dont start programming with haskell that probably just leads to a path of frustration

I don't think starting with Haskell is harder than starting with typical procedural language. To the contrary I think expectations from procedural language make it harder to learn Haskell.
The downside IMHO will be that now you will be frustrated when learning procedural language afterwards. Especially given how elegant algebraic data types and pattern matching is.
 
I don't think starting with Haskell is harder than starting with typical procedural language. To the contrary I think expectations from procedural language make it harder to learn Haskell.
The downside IMHO will be that now you will be frustrated when learning procedural language afterwards. Especially given how elegant algebraic data types and pattern matching is.
i think a new programmer might find pattern matching and adts more elegant once they've already had some fun telling their code to execute steps in an imperative manner, and are now wondering why their data structures are all caveman tier
i really don't think you can show haskell to a random retard and have them say "hmm. i see" because even i have no idea what haskell retards are talking about half the time and new programmers have no idea what i'm talking about half the time
it might be a neat thing to show them early on as a bit of a side note but i expect a lot of "i have to do WHAT to destructively mangle [my words for something they would find rather hard to explain with a haskell nigger around] this thing, screw this i'm going to find somebody who can teach me javascript"
 
I think procedural programming is way easier to grasp - "It's just like writing a recipe :)"
yeah you start off with that and then you say "ok so you know how easy it is to hang yourself with just steps, and how hard it is to trace through the complex series of steps you always make? here are some powerful abstractions (higher-order functions, objects, advanced data structures, etc...) so you can write bigger programs without blowing yourself up"
THEN you can introduce the higher-order stuff that lisp and haskell provide, but only after the student sees a reason to have the stuff (and if they don't, maybe they should stop programming quick before becoming the next yandaredev)
i think if you sat down a completely new programmer and talked about cool haskell shit (e.g. lazy evaluation, purity, and how monads turn the world inside out to contain side effects) instead of "write this to print to screen. write this to get input and store it in this little box called a variable. write this to..." you would just cause the world's quickest case of burnout and they would be very afraid of touching a keyboard ever again
 
Decided to stop fighting with curses pads and just use a regular window and my old rendering system for now. Working on the Status window and command palette next (just working on placing and rendering it for now) once im done with that ill probably move on to adding shortcuts which should be simple... i think. At the very least simpler than what ive been doing so far i also definitely have to look into multiple files at this junction. in other news i was able to write part of the program inside the text editor, it was just comments but still, i couldnt do that at the start of the month so there's that:)

Python:
import curses
import sys
import os
from dataclasses import dataclass, field

# Shortcut Dictionary
shortcutKeys={}
def debug_buffer_to_file(buffer, filepath="debug_log.txt"):
    with open(filepath, "w", encoding="utf-8") as f:
        for i, line in enumerate(buffer):
            text_line = "".join(chr(c) for c in line)
            ascii_line = " ".join(str(c) for c in line)
            f.write(f"{i:03d}: {text_line}\n")
            f.write(f"     ASCII: {ascii_line}\n")
def window_init():
    pass

def load_file(buffer, filepath):
    """
    This function opens a file provided by the user,
    converts the lines from standard strings to a series of characetrs which are easier,
    for our buffer array to keep track of and modify.
    After converting the lines they're loaded into the buffer for modification.
    (this uses a nested for that loops through the lines array creating an ascii line array to store the asci data
    It then loops through the individual lines and converts them to their ascii numbers
    After which the ascii line array is stored in the buffer)
    """
    #[1}basic error catching system which "tries" to open a provided file

    try:
        with open(filepath, "r", encoding="utf-8")as file:
            lines = file.read().splitlines()
            for line in lines:
                ascii_line = []
                for char in line:
                    ascii_line.append(ord(char))
                buffer.append(ascii_line)

    #{2] if it cannot open the file it will print an error message and then create a blank line instead of crashing the program.

    except (FileNotFoundError, PermissionError) as e:
        print(f"[!] Could not open file '{filepath}': {e}")
        buffer.append([])       
    return buffer
          

def save_file(buffer, filepath):
    """This function opens the file provided by the user,
    Converts the lines found in the buffer back to standard strings,
    after which it writes these lines to the file and closes it"""

    content = ""
    for line in buffer:
        for column in line:
          content += chr(column)
        content += "\n"
      
    with open(filepath, "w", encoding="utf-8") as file:
        file.write(content)


# def buffer_renderer(screen, buffer: list, row: int, column: int, r_offset: int, c_offset: int):
#     """This function handles rendering whats in the buffer to the terminal screen.
#        It loops through each row and adds a buffer row to represent it.

#        If the buffer rows extend past the length of the buffer,
#        it moves the screen down by a row and clears the screen.

#        For each character column, offset by the horizontal scroll (c_offset),
#        it tries to render the character from the buffer.
#        If the buffer column is out of bounds for a given row (e.g., the line is shorter than the visible width),
#        it skips rendering at that position, leaving the rest of the screen cell empty or cleared."""
  
#     for rw in range(row):
#             buffer_row = rw + r_offset
#             if buffer_row >=len(buffer):
#                 screen.move(rw, 0)
#                 screen.clrtoeol()
#                 continue

#             for cl in range (column):
#                 buffer_column = cl + c_offset
#                 screen.move(rw, cl)
#                 try:
#                     screen.addch(rw, cl,buffer[buffer_row][buffer_column])
#                 except IndexError:
#                     break
#                 except curses.error:
#                     pass
#             screen.clrtoeol()
#     pass

def visual_cursor_renderer(screen, cursor):
        """This function handles rendering the visual cursor
        The visual cursor is the cursor found inside the terminal"""

        try:
            curses.curs_set(0)
        except curses.error:
            pass

        y = cursor.row - cursor.row_offset
        x = cursor.column - cursor.column_offset
        # Tell curses where to draw the visual cursor, based on scroll offset and logical cursor
        screen.move(y, x)

        try:
            curses.curs_set(1)
        except curses.error:
            pass


@dataclass(slots=True)
class StatusWindow:
    """This class will house a simple window which displays various important pieces of information about a specific file"""
    buffer: list
    width: int
    height: int
    cursor: object
    status: str = field(init= False)
    win: object = field(init= False)
 

    def __post_init__(self):
        self.height-1
        self.status = f"{self.cursor.row+1}/{len(self.buffer)}  Col:{self.cursor.column+1}  {int((self.cursor.row+1)/len(self.buffer)*100)}% {self.src}"
    def render(self):
        pass

@dataclass(slots=True)
class CommandBox:
    def __init__(self):
        pass


@dataclass(slots=True)
class ContentBufferWindow:
    """This class creates a window which is responsible for displaying the workable area of the text editor."""

  
    buffer: list
    cursor: object
    width: int
    height: int
    win: object = field(init=False)


    def __post_init__(self):
        # Adjust height (e.g., reserve one line for status bar)
        self.height -= 1
        self.win = curses.newwin(self.height, self.width, 0, 0)
  
    def render(self):
        """This function handles rendering whats in the buffer to the terminal screen.
       It loops through each row and adds a buffer row to represent it.

       If the buffer rows extend past the length of the buffer,
       it moves the screen down by a row and clears the screen.

       For each character column, offset by the horizontal scroll (c_offset),
       it tries to render the character from the buffer.
       If the buffer column is out of bounds for a given row (e.g., the line is shorter than the visible width),
       it skips rendering at that position, leaving the rest of the screen cell empty or cleared."""
      
        self.win.clear()
        for rw in range(self.height):
            buffer_row = rw + self.cursor.row_offset
            if buffer_row >=len(self.buffer):
                self.win.move(rw, 0)
                self.win.clrtoeol()
                continue

            for cl in range (self.width):
                buffer_column = cl + self.cursor.column_offset
                self.win.move(rw, cl)
                try:
                    self.win.addch(rw, cl,self.buffer[buffer_row][buffer_column])
                except IndexError:
                    break
                except curses.error:
                    pass
            self.win.clrtoeol()
        self.win.refresh()
    pass

@dataclass(slots=True)
class Cursor:
    """This class handles Cursor initialization and application.
    It needs to be aware of the cursors logical position, meaning its position within the editors buffer
    COMPONENTS:
    >> buffer         : A reference to the text buffer (a list of strings), allowing the cursor to interact with document content.
    >> row            : The current logical row index within the buffer.
    >> column         : The current logical column index within the current buffer row.
    >> row_offset     : The number of rows the screen has scrolled down from the top of the buffer; determines vertical viewport start.
    >> column_offset  : The number of columns the screen has scrolled right from the start of each line; determines horizontal viewport start.
    """

    buffer: list
    row_offset: int = 0
    row: int = 0
    column_offset: int = 0
    column: int = 0
      
    def cursor_scrolling(self, term_column, visible_rows):
        """This function takes the available column and row space and moves the visual and logical terminal between its boundries"""

        if self.column < self.column_offset:
            self.column_offset =self.column
        if self.column >= self.column_offset + term_column:
            self.column_offset = self.column - term_column +1

      
        if self.row < self.row_offset:
            self.row_offset = self.row
        if self.row >= self.row_offset + visible_rows:
            self.row_offset = self.row - visible_rows +1

    def cursor_actions(self, ch):
        """This Function takes the character recieved from getch()
        If the character is an arrow key it moves both the visual and logical cursor to the new position"""
      
        #LeftMovement
        if ch == curses.KEY_LEFT:
            if self.column !=0:
                self.column -=1
            elif self.row > 0:
                self.row -=1
                self.column = len(self.buffer[self.row])

        if ch == curses.KEY_RIGHT:
            if self.column < len(self.buffer[self.row]):
                self.column+=1
            elif self.row<len(self.buffer)-1:
                self.row +=1
                self.column = 0

      
        if ch == curses.KEY_UP:
            if self.row >0:
                self.row -=1
                #self.column = len(self.buffer[self.row])
        if ch ==curses.KEY_DOWN:
            if self.row < len(self.buffer)-1:
                self.row +=1
                #self.column = len(self.buffer[self.row])

class WorkspaceManager:
    """This class will manage:
    >>The different windows created,
    >>inputs passed
    >>Commands maybe?(not sure yet)
    >>etc(ill update as i go along)"""
    def __init__(self,):
        pass


def main(stdscr):
    # Initialize the screen
    #NOTE(
    # WILL MAKE A SPECIFIC FUNCTION FOR SCREEN INITIALIZATION
    #)

    mainscreen = stdscr           
    curses.noecho()             # Makes it so that non letter inputs arent displayed on the screen when typing
    curses.raw()                # Make it so that characters are recieved as the are sent to the terminal
    mainscreen.keypad(1)            # Enables the special keys like arrows and whatnot
  

    buffer = []

  
    src ='noname.txt'                                        # Sets the default file name
    (term_row,term_column)=mainscreen.getmaxyx()                  # Sets the terminal dimensions
    visible_rows = term_row-1                               # Sets aside a row for the line indicator/bottom info giver thingy
  
    cursor = Cursor(buffer=buffer)         # Creates and store the cursor in its own class

    content_window = ContentBufferWindow(buffer=buffer, cursor= cursor, width= term_column, height=term_row)
    # Handles file loading
    if len(sys.argv) ==2:
        src = sys.argv[1]
        load_file(buffer, src)       
    else:
        load_file(buffer, src)
  
    #NOTE(
    # Not sure i need this waiting to see if this breaks an edge case or something
    # The video i followed didnt go into great detail on why choices were made so i just keep commenting things out to text their usefullness
    # Hence large blocks of commented out code may be found all about the program thee will be removed eventually.
    #)

    while True:
        mainscreen.move(0,0)   #positions the cursor to top left

        #SCROLLING
        cursor.cursor_scrolling(term_column=term_column, visible_rows= content_window.height)


        #SCREEN RENDERING
        #buffer_renderer(screen= mainscreen, buffer=buffer, row=visible_rows, column=term_column, r_offset=cursor.row_offset, c_offset= cursor.column_offset )
        content_window.render()


        #debug_buffer_to_file(buffer=buffer)
        #STATUS BAR NOTE: Soon to be status window.
        status = f"{cursor.row+1}/{len(buffer)}  Col:{cursor.column+1}  {int((cursor.row+1)/len(buffer)*100)}%                                      {src}"
        mainscreen.addstr(term_row - 1, 0, status[:term_column-1], curses.A_REVERSE)
      
      
        #CURSOR RENDERING
        visual_cursor_renderer(screen=mainscreen, cursor = cursor)
        #screen.refresh()
      
      

        #input manager
        ch =mainscreen.getch()

        #Text insert 
        if ch != ((ch) & 0x1f) and ch < 128:
            buffer[cursor.row].insert(cursor.column, ch)
            cursor.column +=1

        #enter handling 
        if chr(ch) in "\n\r":
            line = buffer[cursor.row][cursor.column:]
            buffer[cursor.row] = buffer[cursor.row][:cursor.column]
            cursor.row+=1
            cursor.column = 0
            buffer.insert(cursor.row, line)
      
        #Backspace handling
        if ch in [8,263]:
            if cursor.column:
                try:
                    cursor.column -=1
                    del buffer[cursor.row][cursor.column]
                except IndexError:
                    cursor.column = len(cursor.buffer[cursor.row])

            elif cursor.row>0:
                line = buffer[cursor.row][cursor.column:]
                del buffer[cursor.row]
                cursor.row -=1
                cursor.column = len(buffer[cursor.row])
                buffer[cursor.row] += line

        #CURSOR ACTIONS   
        cursor.cursor_actions(ch=ch)

      


        #NOTE: NO CLUE WHAT THIS DID, MIGHT HAVE BEEN SOME LEFT OVER CODE DEALING WITH BUFFER RENDERING
        #if cursor.row < len(buffer):
            #rw = buffer[cursor.row]
        #else:
            #None
        #rwlen = len(rw) if rw is not None else 0
        #if cursor.column >rwlen:
            #cursor.column = rwlen

        #save and quit
        if ch == (ord("s") & 0x1f):  # Ctrl+S
            save_file(buffer=buffer, filepath=src)

        if ch == (ord("q") & 0x1f):  # Ctrl+Q
            sys.exit()


curses.wrapper(main) #this protects the terminal
What are the best, free resources to start learning how to code?
well other than the obvious youtube beginner tutorials, id suggest finding something you want to do or automate and trying to make it (or improve it, if it already exists).
 
Last edited:
well other than the obvious youtube beginner tutorials, id suggest finding something you want to do or automate and trying to make it (or improve it, if it already exists).
theres a gigachad on this thread who started making a text editor a while ago and is now starting to use the text editor to edit itself
 
i think if you sat down a completely new programmer and talked about cool haskell shit (e.g. lazy evaluation, purity, and how monads turn the world inside out to contain side effects) instead of "write this to print to screen. write this to get input and store it in this little box called a variable. write this to..." you would just cause the world's quickest case of burnout and they would be very afraid of touching a keyboard ever again
cough HTDP cough

we get one of you every 2 weeks so there's a thread about it but i actually can't find it in search so i will tell you:
Nigger, I literally linked it 2 pages ago.

Further evidence of why it should be linked to more often.
 
cough HTDP cough
never read it although isn't it a scheme book? scheme isn't quite as autistic as haskell is imo and could feasibly be used for ultimate beginners
Nigger, I literally linked it 2 pages ago.
yes and im too lazy to skim 2 pages so i searched for the thread instead and kf's broken ass search system didn't return it so i typed a simple response
 
I don't think starting with Haskell is harder than starting with typical procedural language
I actually experienced something quite similar. I've decided to get a master's degree in CS after doing a bachelor's degree in an unrelated field and one of the first classes I've had was about functional programming in Haskell.
On every step on the way I felt like I was missing a lot of information and books like Learn you a Haskell (supposedly for beginners) did not make things much clear for me. I had quite a hard time wrapping my head around how this language worked and it only clicked together after almost failing the class completely.
Even as a teenager I was able to do stuff in languages like PHP and Delphi with minimal supervision and research. I can't imagine being a clueless 12 year old again and starting off with Haskell.
I also got close to nothing out of learning this language because no one bothers to do anything fun in it. So it's not like I got to build on top of that knowledge anyway.
 
Back