Skip to content

Objeck is a modern object-oriented programming language with functional features tailored for machine learning. It emphasizes expression, simplicity, portability, and scalability. The programming environment consists of a compiler, virtual machine, REPL shell, and command line debugger with IDE plugins.

License

Notifications You must be signed in to change notification settings

objeck/objeck-lang

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Versatile, Scalable and Efficient

An Objeck


GitHub CodeQL GitHub CI Coverity SCA

Releases

  • v2024.10.0 (current)

    • Bug fix (#503)
  • v2024.9.0

    • JSON-RPC support
    • Bug fixes
  • v2024.8.0

    • Compiler updates (done)
      • Dead code checker
      • Improved type inference for generic types
  • v2024.7.1

    • Perplexity API support
    • Bug fixes

Examples

# simple openai and perplexity inference 
use API.OpenAI, API.OpenAI.Chat, Collection;

class OpenAICompletion {
  @is_pplx : static : Bool;

  function : Main(args : String[]) ~ Nil {
    if(args->Size() <> 1) {
      ">>> Error: Token file required <<"->ErrorLine();
      Runtime->Exit(1);
    };

    token := GetApiKey(args[0]);
    if(token = Nil) {
      ">>> Unable to use API key <<"->PrintLine();
      Runtime->Exit(1);
    };

    model : String;
    if(@is_pplx) {
      Completion->SetBaseUrl("https://api.perplexity.ai");
      model := "llama-3-sonar-small-32k-online";
    }
    else {
      model := "gpt-4o";
    };
    
    message := Pair->New("user", "What is the longest road in Denver?")<String, String>;
    completion := Completion->Complete(model, message, token);
    if(completion <> Nil) {
      choice := completion->GetFirstChoice();
      if(choice = Nil) {
        ">>> Error: Unable to complete query <<"->ErrorLine();
        Runtime->Exit(1);
      };

      message := choice->GetMessage()<String, String>;
      if(message = Nil) {
        ">>> Error: Unable to read response <<"->ErrorLine();
        Runtime->Exit(1);
      };

      message->GetSecond()->PrintLine();
    };
  }

  function : GetApiKey(filename : String) ~ String {
    token := System.IO.Filesystem.FileReader->ReadFile(filename);
    if(token <> Nil) {
      token := token->Trim();
      if(<>token->StartsWith("sk-") & <>token->StartsWith("pplx-")) {
        ">>> Unable to read token from file: '{$filename}' <<"->PrintLine();
        Runtime->Exit(1);
      };

      if(token->StartsWith("pplx-"))  {
        @is_pplx := true;
      };

      return token;
    };

    return Nil;
  }
}
# create an image from a prompt
use API.OpenAI, API.OpenAI.FineTuning, System.IO.Filesystem, Data.JSON;

class CreateImage {
  function : Main(args : String[]) ~ Nil {
    image := Image->Create("Create an image of two old steel gears with a transparent background", token);
    if(image <> Nil) {
      urls := image->GetUrls();
      each(url in urls) {
        url->ToString()->PrintLine();
      };
    };
  }
 }
# image identification 
use API.Google.Gemini, System.IO.Filesystem;

class IdentifyImage {
  function : Main(args : String[]) ~ Nil {
    content := Content->New("user")->AddPart(TextPart->New("What number is this image showing?"))
      ->AddPart(BinaryPart->New(FileReader->ReadBinaryFile("thirteen.png"), "image/png"))
      ->AddPart(TextPart->New("Format output as JSON"));

    candidates := Model->GenerateContent("models/gemini-pro-vision", content, EndPoint->GetApiKey());
    if(candidates->Size() > 0) {
      candidates->First()->GetAllText()->Trim()->PrintLine();
    };
  }
}
# tune ML model
use Collection, API.OpenAI, System.IO.Filesystem, Data.JSON, Data.CSV;

class TuneAssist {
  function : Main(args : String[]) ~ Nil {
    if(args->Size() = 1) {
      filename := args[1];
      file := API.OpenAI.File->LoadOrCreate(filename, "fine-tune", token);

      name := file->GetFilename();
      id := file->GetId();
      "file='{$name}', id='{$id}'"->PrintLine();
      tuning_job := Tuner->Create("gpt-3.5-turbo", id, token);
      tuning_job->ToString()->PrintLine();
    }
  }
}
# text to speech
use Web.HTTP, Collection, Data.JSON, API.OpenAI.Audio;

class Embaddings {
  function : Main(args : String[]) ~ Nil {
    if(args->Size() = 1) {
      message := args[1];
      response := API.OpenAI.Audio.Speech->Speak("tts-1", message, "fable", "mp3", token)<String, ByteArrayRef>;        
      
      if(response->GetFirst()->Has("audio")) {
        System.IO.Filesystem.FileWriter->WriteFile("speech.mp3", response->GetSecond()->Get());
      };
    }
  }
}

Design [1]

  • Object-oriented and functional
  • Cross-platform support for Linux, macOS, and Windows (including Docker and RPI 3/4/5)
  • JIT-compiled runtimes (ARM64 and AMD64)
  • REPL shell
  • LSP plugins for VSCode, Sublime, Kate, and more
  • API documentation

Libraries [2]

Features

Object-oriented

Inheritance

class Triangle from Shape {
  New() {
    Parent();
  }
}

Interfaces

class Triangle from Shape implements Color {
  New() {
    Parent();
  }

  method : public : GetRgb() ~ Int {
    return 0xadd8e6;
  }
}

interface Color {
  method : virtual : public : GetRgb() ~ Int;
}

Type Inference

value := "Hello World!";
value->Size()->PrintLine();

Anonymous Classes

interface Greetings {
  method : virtual : public : SayHi() ~ Nil;
}

class Hello {
  function : Main(args : String[]) ~ Nil {
    hey := Base->New() implements Greetings {
      New() {}

      method : public : SayHi() ~ Nil {
        "Hey..."->PrintLine();
      }
    };
}

Reflection

klass := "Hello World!"->GetClass();
klass->GetName()->PrintLine();
klass->GetMethodNumber()->PrintLine();

Dependency Injection

value := Class->Instance("System.String")->As(String);
value += "510";
value->PrintLine();

Generics

map := Collection.Map->New()<IntRef, String>;
map->Insert(415, "San Francisco");
map->Insert(510, "Oakland");
map->Insert(408, "Sunnyvale");
map->ToString()->PrintLine();

Type Boxing

list := Collection.List->New()<IntRef>;
list->AddBack(17);
list->AddFront(4);
(list->Back() + list->Front())->PrintLine();

Static import

use function Int;

class Test {
  function : Main(args : String[]) ~ Nil {
    Abs(-256)->Sqrt()->PrintLine();
  }
}

Serialization

serializer := System.IO.Serializer->New();
serializer->Write(map);
serializer->Write("Fin.");
bytes := serializer->Serialize();
bytes->Size()->PrintLine();

Functional

Closures and Lambda Expressions

funcs := Vector->New()<FuncRef<IntRef>>;
each(i : 10) {
  funcs->AddBack(FuncRef->New(\() ~ IntRef : () 
    => i->Factorial() * funcs->Size())<IntRef>);
};

each(i : funcs) {
  value := funcs->Get(i)<FuncRef>;
  func := value->Get();
  func()->Get()->PrintLine();
};

First-Class Functions

@f : static : (Int) ~ Int;
@g : static : (Int) ~ Int;

function : Main(args : String[]) ~ Nil {
  compose := Composer(F(Int) ~ Int, G(Int) ~ Int);
  compose(13)->PrintLine();
}

function : F(a : Int) ~ Int {
  return a + 14;
}

function : G(a : Int) ~ Int {
  return a + 15;
}

function : native : Compose(x : Int) ~ Int {
  return @f(@g(x));
}

function : Composer(f : (Int) ~ Int, g : (Int) ~ Int) ~ (Int) ~ Int {
  @f := f;
  @g := g;
  return Compose(Int) ~ Int;
}

Host Support

Unicode

"Καλημέρα κόσμε"->PrintLine();

File System

content := Sytem.IO.Filesystem.FileReader->ReadFile(filename);
content->Size()->PrintLine();
Sytem.IO.Filesystem.File->Size(filename)->PrintLine();

Sockets

socket->WriteString("GET / HTTP/1.1\nHost:google.com\nUser Agent: Mozilla/5.0 (compatible)\nConnection: Close\n\n");
line := socket->ReadString();
while(line <> Nil & line->Size() > 0) {
  line->PrintLine();  
  line := socket->ReadString();
};
socket->Close();

Named Pipes

pipe := System.IO.Pipe->New("foobar", Pipe->Mode->CREATE);
if(pipe->Connect()) {
  pipe->ReadLine()->PrintLine();
  pipe->WriteString("Hi Ya!");
  pipe->Close();
};

Threads

class CaculateThread from Thread {
  ...
  @inc_mutex : static : ThreadMutex;

  New() {
    @inc_mutex := ThreadMutex->New("inc_mutex");
  }
  
  method : public : Run(param : System.Base) ~ Nil {
    Compute();
  }

  method : native : Compute() ~ Nil {
    y : Int;

    while(true) {
      critical(@inc_mutex) {
        y := @current_line;
        @current_line+=1;
      };
      ...
    };
  }
}

Date/Times

yesterday := System.Time.Date->New();
yesterday->AddDays(-1);
yesterday->ToString()->PrintLine();

Screenshots

VS Code Debugger Dungeon Crawler Platformer Windows Utility
alt text alt text alt text alt text alt text