От переводчика: эта статья — перевод материала, написанного программистом Аластером Парагасом (Alastair Paragas) из Apple.Он работал с такими языками программирования, как Javascript, Python, PHP, Java, Scala, Haskell, Swift и Rust. Аластер делится собственными размышлениями на тему выбора и изучения «своего» языка, ведь этот вопрос актуален как для новичков, так и для профессионалов, которые хотят выбрать новый инструментарий.
Изучаете ли вы язык программирования ради трудоустройства или повышения квалификации или же это чистой воды хобби, рано или поздно вам придется выбирать между ними. Как это сделать? Вопрос непростой, но ответить на него можно так: каждый день это делают тысячи программистов. Чтобы облегчить себе задачу, стоит следовать нескольким принципам.
Skillbox рекомендует: Практический курс «Профессия Веб?разработчик»..
Напоминаем: для всех читателей Хабра — скидка 10 000 рублей при записи на любой курс Skillbox по промокоду «Хабр»
from concurrent.futures import ThreadPoolExecutor
from http.client import HTTPException
from urllib import request
from typing import Union, Dict, Any, List
def get_request_task(url: str) -> Union[List[Dict[str, Any]], None]:
try:
contents = None
with request.urlopen(url) as response:
contents = response.read()
return contents
except HTTPException:
return None
with ThreadPoolExecutor() as executor:
for result in executor.map(get_request_task, [
"https://jsonplaceholder.typicode.com/posts",
"https://jsonplaceholder.typicode.com/comments",
"https://jsonplaceholder.typicode.com/albums"
]):
if result is None:
print("Something terrible has happened!")
else:
print(result)
import Foundation
import Dispatch
func getRequestTask(url: String, dispatchGroup: DispatchGroup) {
dispatchGroup.enter()
let request = URLRequest(url: URL(string: url)!)
let task = URLSession(configuration: URLSessionConfiguration.default).dataTask(
with: request,
completionHandler: {
(data, response, error) in
if let data = data {
if let dataAsString = String(data: data, encoding: .utf8) {
print(dataAsString)
dispatchGroup.leave()
return
}
}
print("Something terrible has happened!")
dispatchGroup.leave()
}
)
task.resume()
}
let requestDispatchGroup = DispatchGroup()
for url in [
"https://jsonplaceholder.typicode.com/posts",
"https://jsonplaceholder.typicode.com/comments",
"https://jsonplaceholder.typicode.com/albums"
] {
getRequestTask(url: url, dispatchGroup: requestDispatchGroup)
}
requestDispatchGroup.wait()
module Main where
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans.Resource (runResourceT)
import Data.Conduit (($$+-), ($=+), runConduit)
import Data.Conduit.List (mapM_, map, filter, catMaybes)
import Data.Text (unpack)
import Data.Maybe (fromJust)
import Web.Twitter.Types
(StreamingAPI(SStatus, SRetweetedStatus)
, Status(Status), statusText, statusLang
, RetweetedStatus(RetweetedStatus), rsRetweetedStatus
)
import Web.Twitter.Conduit.Stream (stream)
-- Filters Twitter tweets that are written only in English
filterEnglishTweets :: StreamingAPI -> Bool
filterEnglishTweets tweet =
let
langIsEnglish (Status {statusLang=language}) = case language of
Just "en" -> True
_ -> False
in case tweet of
SStatus statusObj -> langIsEnglish statusObj
SRetweetedStatus (RetweetedStatus {rsRetweetedStatus=statusObj}) ->
langIsEnglish statusObj
_ -> False
-- Filters Twitter tweets that are original posts
tweetParser :: StreamingAPI -> Maybe String
tweetParser tweet = case tweet of
SStatus (Status {statusText=status}) -> Just $ unpack status
SRetweetedStatus (RetweetedStatus {rsRetweetedStatus=rstatus}) ->
Just $ unpack $ statusText rstatus
_ -> Nothing
main :: IO ()
main = do
-- a bunch of connection setup details to Twitter
{-
Imagine a stream/production line of continually incoming Twitter tweets
out of this stream, non-English tweets are removed
each remaining tweet then gets packaged into one of two forms
- one for original tweets
- one for non-original tweets (retweets and whatnot)
We then only grab packaged forms of original tweets and display them!
-}
in runResourceT $ do
stream <- stream twitterInfo connectionManager apiRequest
stream $=+
Data.Conduit.List.filter filterEnglishTweets $=+
Data.Conduit.List.map tweetParser $=+
Data.Conduit.List.catMaybes $$+-
Data.Conduit.List.mapM_ (liftIO . putStrLn)
import gc
import ctypes
gc.set_debug(gc.DEBUG_SAVEALL)
class PyObject(ctypes.Structure):
_fields_ = [("refcnt", ctypes.c_long)]
object1 = {}
object2 = {}
object3 = {}
object1['reference_to_2'] = object2
object2['reference_to_1'] = object1
object3['some_key'] = 1
object1_memory_address = id(object1)
object2_memory_address = id(object2)
object3_memory_address = id(object3)
print "Before garbage collection --->"
print "Refcount for object1: {count}".format(
count=PyObject.from_address(object1_memory_address).refcnt
)
print "Refcount for object2: {count}".format(
count=PyObject.from_address(object2_memory_address).refcnt
)
print "Refcount for object3: {count}".format(
count=PyObject.from_address(object3_memory_address).refcnt
)
del object1, object2, object3
gc.collect()
print "After garbage collection --->"
print "Refcount for object1: {count}".format(
count=PyObject.from_address(object1_memory_address).refcnt
)
print "Refcount for object2: {count}".format(
count=PyObject.from_address(object2_memory_address).refcnt
)
print "Refcount for object3: {count}".format(
count=PyObject.from_address(object3_memory_address).refcnt
)
print "Objects that cannot be cleaned up by reference counting: --->"
for x in gc.garbage:
print x
class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
deinit { print("\(name) is being deinitialized") }
}
class Apartment {
let unit: String
init(unit: String) { self.unit = unit }
weak var tenant: Person?
deinit { print("Apartment \(unit) is being deinitialized") }
const https = require("https");
const urlList = [
"https://reqres.in/api/users?page=1",
"https://reqres.in/api/users?page=2",
"https://reqres.in/api/users?page=3"
];
function getSiteContents(url) {
return new Promise(function (resolve, reject) {
https.get(url, function (res) {
var bodyData = "";
res.on("data", function (chunk) {
bodyData += chunk;
});
res.on("end", function () {
resolve(bodyData);
});
res.on("error", function (error) {
reject(error.message);
});
});
});
}
// One way we can proceed with execution
// Make one Promise out of a list of Promises
Promise.all(urlList.map(getSiteContents))
.then(function (siteContents) {
console.log("Promise based execution --->");
console.log(siteContents);
});
// Another way we can proceed with execution
// "async" is an ES7 feature that makes our Promise/async I/O code look
// more synchronous
async function main () {
const siteContents = await Promise.all(urlList.map(getSiteContents))
console.log("Main() based execution --->");
console.log(siteContents);
}
main();
// As Promises will happen in some future time, this will happen first
console.log("This console.log will most likely happen first");
<?php
// Accumulator gets passed around for reuse - function as a value
$accumulator = function (
string $accumulated_string,
string $mapped_list_element
) {
return $accumulated_string . $mapped_list_element . "\n";
};
// Notice how array_map, array_filter and array_reduce
// accept functions as parameters - they are higher order functions
$mapped_array = array_reduce(
array_map(
function (int $list_element): string {
return "A list element: " . $list_element;
},
[1, 2, 3, 4]
),
$accumulator,
""
);
echo "Mapped Array: \n";
echo $mapped_array;
$filtered_array = array_reduce(
array_filter(
[1, 2, 3, 4],
function (int $list_element): bool {
return $list_element > 2;
}
),
$accumulator,
""
);
echo "Filtered Array: \n";
echo $filtered_array;
// Closures "enclose" over their surrounding state
// The $closure_incrementer function here returns a function
// making it a higher order function.
echo "Closure Incrementer: \n";
$closure_incrementer = function () {
$internal_variable = 0;
return function () use (&$internal_variable) {
return $internal_variable += 1;
};
};
$instance = $closure_incrementer();
echo $instance() . " is equal to 1\n";
echo $instance() . " is equal to 2\n";
func containedClosureIncrementer() -> (() -> Int) {
var anInt = 0
func incrementer() -> Int {
anInt = anInt + 1
return anInt
}
return incrementer
}
func containedClosureIncrementer2() -> () -> Int {
var anInt = 0
return {
anInt = anInt + 1
return anInt
}
}
let closureIncrementer = containedClosureIncrementer()
print("containedClosureIncrementer call - should be 1: \(closureIncrementer() == 1)")
print("containedClosureIncrementer call - should be 2: \(closureIncrementer() == 2)")
var someOptionalValue: Optional<String> = nil;
print("Optional - someOptionalValue is null: \(someOptionalValue == nil)")
someOptionalValue = "real value"
print("Optional - someOptionalValue is 'real value' \(someOptionalValue == "real value")")
(["real value", nil] as Array<Optional<String>>).forEach({
someOptionalValue in
if let someValue = someOptionalValue {
if someValue.hasPrefix("real") {
print("someValue: has real")
} else {
print("someValue: doesn't have real")
}
} else {
print("someValue: has nil")
}
})
if (someOptionalValue ?? "").hasPrefix("real") {
print("Has real 2")
} else {
print("Doesn't have real")
}
let numbersList: [Int] = Array(1...10)
print("List of numbers 1 to 10: \(numbersList)")
let numbersListTimes2 = numbersList.map({
(someNumber: Int) -> Int in
let multiplicand = 2
return someNumber * multiplicand
})
let numbersListTimes2V2 = numbersList.map({
number in number * 2
})
let numbersListTimes2V3 = numbersList.map {
$0 * 2
}
print("List of numbers * 2: \(numbersListTimes2)")
print("V1, V2 Map operations do the same thing: \(numbersListTimes2 == numbersListTimes2V2)")
print("V1, V3 Map operations do the same thing: \(numbersListTimes2 == numbersListTimes2V3)")
func testGuard() {
let someOptionalValue: Optional<String> = nil;
guard let someOptionalValueUnwrapped = someOptionalValue else {
print("testGuard: Thrown exception - nil value")
return
}
print("testGuard: no exception - non-nil value: \(someOptionalValueUnwrapped)")
}
testGuard()
class RuntimeError: Error {}
[{throw RuntimeError()}, {1} as () throws -> Int].forEach {
let returnValue = try? $0()
if let returnValueUnwrapped = returnValue {
print("List of closures: A normal value was returned \(returnValueUnwrapped)")
} else {
print("List of closures: An error was thrown")
}
}
Skillbox рекомендует:
- Практический 4-х месячный курс «Python-разработчик с нуля».
- Онлайн-курс «PHP-разработчик с нуля до PRO».
- Практический курс «Профессия Frontend-разработчик».
К сожалению, не доступен сервер mySQL